Weave Code
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

Sonata Classification Bundle Laravel Package

awaresoft/sonata-classification-bundle

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation via Composer** (if not symlinked):
   ```bash
   composer require awaresoft/sonata-classification-bundle

Note: Follow the README’s symlink instructions if modifying locally.

  1. Enable the Bundle in config/bundles.php:

    return [
        // ...
        Awaresoft\SonataClassificationBundle\SonataClassificationBundle::class => ['all' => true],
    ];
    
  2. Database Setup:

    • Run migrations (if provided) or manually create tables for classifications (e.g., classification, classification_category).
    • Example migration (adjust per your needs):
      php bin/console make:migration
      php bin/console doctrine:migrations:migrate
      
  3. First Use Case:

    • Create a Classification Model: Extend Awaresoft\SonataClassificationBundle\Entity\Classification or use traits like ClassifiableInterface.
      // src/Entity/Product.php
      use Awaresoft\SonataClassificationBundle\Entity\ClassificationTrait;
      
      class Product
      {
          use ClassificationTrait;
          // ...
      }
      
    • Define Classifications via YAML/Doctrine:
      # config/sonata_classification.yml
      sonata_classification:
          categories:
              - { name: 'Product Type', slug: 'product_type' }
              - { name: 'Color', slug: 'color' }
          classifications:
              - { category: 'product_type', name: 'Electronics', slug: 'electronics' }
              - { category: 'color', name: 'Red', slug: 'red' }
      
  4. Assign Classifications to Entities: Use the ClassifiableInterface methods:

    $product = new Product();
    $product->addClassification($classificationEntity);
    $entityManager->persist($product);
    

Implementation Patterns

Core Workflows

1. Hierarchical Classification Management

  • Tree Structure: Leverage Awaresoft\SonataClassificationBundle\Model\ClassificationInterface for parent-child relationships.
    $subCategory = new Classification();
    $subCategory->setParent($parentCategory);
    $subCategory->setName('Subcategory');
    
  • Admin Panel: Use SonataAdminBundle integration (if available) to manage classifications via UI:
    # config/packages/sonata_admin.yml
    sonata_admin:
        options:
            models:
                Awaresoft\SonataClassificationBundle\Entity\Classification: ~
    

2. Entity Classification

  • Traits for Reusability: Use ClassificationTrait in multiple entities to avoid duplication:
    class Book implements ClassifiableInterface
    {
        use ClassificationTrait;
        // ...
    }
    
  • Querying Classified Entities:
    $classifiedProducts = $entityManager->getRepository(Product::class)
        ->findBy(['classifications' => $classification]);
    

3. Dynamic Classification Assignment

  • Form Integration: Use Symfony Forms to let users assign classifications:
    $builder->add('classifications', EntityType::class, [
        'class' => Classification::class,
        'multiple' => true,
        'expanded' => true,
    ]);
    
  • Validation: Add constraints to enforce classification rules:
    use Awaresoft\SonataClassificationBundle\Validator\Constraints\ValidClassification;
    
    /**
     * @ValidClassification(groups={"classification"})
     */
    class Product { ... }
    

4. API Exposure

  • Serialization: Use Symfony Serializer to expose classifications in APIs:
    #[Groups(['api'])]
    #[SerializedName('classifications')]
    public function getClassifications(): array
    {
        return $this->classifications->map(fn($c) => $c->getSlug());
    }
    
  • GraphQL: Integrate with API Platform or custom resolvers:
    type Product {
        classifications: [Classification!]!
    }
    

5. Caching Strategies

  • Cache Classification Trees: Use Symfony Cache component to optimize hierarchical queries:
    $cache = $container->get('cache.app');
    $key = 'classification_tree_' . $category->getSlug();
    $tree = $cache->get($key, function() use ($category) {
        return $category->getChildren(); // Custom method
    });
    

Integration Tips

Symfony Ecosystem

  • Doctrine: Ensure Classification entities are mapped correctly in orm.xml or annotations.
  • Twig: Create custom Twig extensions for classification logic:
    {% for classification in product.classifications %}
        {{ classification.getName() }}
    {% endfor %}
    
  • Events: Listen to classification changes:
    // src/EventListener/ClassificationListener.php
    public function onClassificationUpdate(ClassificationEvent $event)
    {
        $classification = $event->getClassification();
        // Log or trigger actions
    }
    

Performance

  • Batch Processing: Use Doctrine Batch operations for bulk classification assignments:
    $em = $this->getEntityManager();
    $em->getConnection()->beginTransaction();
    foreach ($products as $product) {
        $product->addClassification($classification);
        $em->persist($product);
        if ($i % 20 === 0) {
            $em->flush();
            $em->clear();
        }
    }
    $em->getConnection()->commit();
    

Testing

  • Functional Tests:
    public function testClassificationAssignment()
    {
        $client = static::createClient();
        $client->request('POST', '/api/products', [
            'json' => [
                'classifications' => ['electronics', 'red']
            ]
        ]);
        $this->assertResponseIsSuccessful();
    }
    
  • Unit Tests: Mock ClassificationTrait methods:
    $product = $this->createMock(Product::class);
    $product->method('getClassifications')->willReturn([$mockClassification]);
    

Gotchas and Tips

Pitfalls

  1. Backward Compatibility:

    • The bundle enforces strict BC rules. Avoid modifying core methods without incrementing major version numbers.
    • Fix: Use feature flags or separate branches for experimental changes.
  2. Symlink Issues:

    • Forgetting to update autoload_psr4.php after symlinking can cause autoloading errors.
    • Fix: Run composer dump-autoload after manual symlink changes.
  3. Circular References:

    • Deeply nested classifications (e.g., 10+ levels) may cause performance issues or stack overflows.
    • Fix: Limit hierarchy depth or use lazy-loading for children.
  4. Missing Doctrine Mappings:

    • If Classification entities aren’t properly mapped, queries will fail silently.
    • Fix: Verify orm.xml or annotations for Classification and related entities.
  5. Concurrent Modifications:

    • Direct database edits (e.g., via SQL) can break the bundle’s expected state.
    • Fix: Use the bundle’s services/methods for all classification operations.

Debugging

  1. Query Logs: Enable Doctrine debug mode to inspect classification queries:

    # config/packages/dev/doctrine.yaml
    doctrine:
        dbal:
            logging: true
            profiling: true
    
  2. Event Listeners: Add debug listeners to trace classification changes:

    public function onClassificationPrePersist(ClassificationEvent $event)
    {
        $this->logger->debug('Classification saved', ['classification' => $event->getClassification()->getSlug()]);
    }
    
  3. Common Errors:

    • "Class not found": Verify the symlink points to /src/Awaresoft.
    • Validation errors: Check ValidClassification constraints and entity mappings.
    • Performance issues: Profile with Xdebug or Blackfire to identify N+1 queries.

Extension Points

  1. Custom Classification Logic:

    • Override Awaresoft\SonataClassificationBundle\Entity\Classification:
      class CustomClassification extends Classification
      {
          private $customField;
      
          // Add getters/setters and business logic
      }
      
  2. New Classification Types:

    • Extend the bundle’s ClassificationType (if available) or create a custom form type:
      class CustomClassificationType extends AbstractType
      {
          public function buildForm(FormBuilderInterface $builder, array $options)
          {
              $builder->add('custom_field', TextType::class);
          }
      }
      
  3. API Extensions:

    • Add custom serialization groups:
      #[Groups(['api', 'export'])]
      public function getClassificationTree(): array
      {
          return $this->getChildren()->map(fn($c) => $c->getSlug());
      }
      
  4. **Admin

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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity