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

Characteristics Bundle Laravel Package

ekyna/characteristics-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to Begin

  1. Installation

    composer require ekyna/characteristics-bundle
    

    Add to config/bundles.php (Symfony) or config/app.php (Laravel wrapper if available):

    Ekyna\CharacteristicsBundle\EkynaCharacteristicsBundle::class => ['all' => true],
    
  2. Database Setup Run migrations (if provided in the bundle):

    php artisan migrate
    

    Check src/Resources/migrations/ for schema (if available).

  3. First Use Case: Define a Characteristic

    use Ekyna\CharacteristicsBundle\Entity\Characteristic;
    
    $characteristic = new Characteristic();
    $characteristic->setName('Color');
    $characteristic->setSlug('color');
    $em->persist($characteristic);
    $em->flush();
    
  4. Key Files to Review

    • src/Resources/config/doctrine/ (Entity mappings)
    • src/DependencyInjection/ (Configuration logic)
    • src/Entity/ (Core models like Characteristic, CharacteristicValue)

Implementation Patterns

Core Workflows

  1. CRUD for Characteristics

    // Create
    $characteristic = $this->getDoctrine()->getRepository(Characteristic::class)->create(['name' => 'Size']);
    
    // Read
    $characteristic = $this->getDoctrine()->getRepository(Characteristic::class)->findOneBy(['slug' => 'size']);
    
    // Update
    $characteristic->setDescription('Product dimensions');
    $em->flush();
    
    // Delete (soft/hard)
    $characteristic->setIsActive(false); // Soft delete
    // OR
    $em->remove($characteristic); // Hard delete
    
  2. Assigning Values to Entities

    // Example: Assign "Red" to a Product
    $product = $entityManager->getRepository(Product::class)->find(1);
    $redValue = $entityManager->getRepository(CharacteristicValue::class)->findOneBy(['slug' => 'red']);
    
    $product->addCharacteristicValue($redValue);
    $entityManager->flush();
    
  3. Filtering Entities by Characteristics

    // Find all products with "Red" color
    $qb = $entityManager->createQueryBuilder();
    $qb->select('p')
       ->from(Product::class, 'p')
       ->join('p.characteristicValues', 'cv')
       ->where('cv.slug = :color')
       ->setParameter('color', 'red');
    
    $products = $qb->getQuery()->getResult();
    
  4. Dynamic Characteristic Selection

    // Get all active characteristics for a category
    $category = $entityManager->getRepository(Category::class)->find(1);
    $characteristics = $category->getCharacteristics()->toArray();
    

Integration Tips

  • Event Listeners: Extend functionality via kernel.events (Symfony) or Laravel’s events config.
    // Example: Log characteristic changes
    $dispatcher->addListener(
        CharacteristicEvents::POST_UPDATE,
        [$this, 'onCharacteristicUpdated']
    );
    
  • API Resources (Laravel): Transform characteristics into API responses:
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'slug' => $this->slug,
            'values' => CharacteristicValueResource::collection($this->values),
        ];
    }
    
  • Form Integration: Use Symfony Forms or Laravel Collectives for frontend binding:
    // Symfony FormBuilder
    $builder->add('characteristics', EntityType::class, [
        'class' => Characteristic::class,
        'choice_label' => 'name',
        'multiple' => true,
    ]);
    

Gotchas and Tips

Pitfalls

  1. Missing Migrations

    • The bundle lacks explicit migration files in the README. Check src/Resources/migrations/ or manually create tables:
      CREATE TABLE characteristics (
          id INT AUTO_INCREMENT PRIMARY KEY,
          name VARCHAR(255) NOT NULL,
          slug VARCHAR(255) NOT NULL UNIQUE,
          is_active BOOLEAN DEFAULT true
      );
      
    • Workaround: Use Doctrine’s schema tool:
      php artisan doctrine:schema:update --force
      
  2. Entity Relationships

    • The bundle assumes a many-to-many relationship between entities (e.g., Product) and CharacteristicValue. Ensure your entity has:
      /**
       * @ORM\ManyToMany(targetEntity="Ekyna\CharacteristicsBundle\Entity\CharacteristicValue")
       */
      private $characteristicValues;
      
    • Fix: Add the relationship manually if missing.
  3. Slug Uniqueness

    • Slugs must be unique across characteristics. Validate in your controller:
      $existing = $em->getRepository(Characteristic::class)->findOneBy(['slug' => $request->slug]);
      if ($existing && $existing->getId() !== $characteristic->getId()) {
          throw new \InvalidArgumentException('Slug already exists.');
      }
      
  4. Performance with Large Datasets

    • Filtering by characteristics can be slow. Use database indexes:
      CREATE INDEX idx_characteristic_values_entity_id ON characteristic_values (entity_id);
      
    • Optimization: Load characteristics lazily:
      $product->getCharacteristicValues()->matching($criteria)->toArray();
      

Debugging Tips

  1. Enable Doctrine Logging

    // config/packages/dev/doctrine.yaml
    doctrine:
        dbal:
            logging: true
            profiling: true
    
    • Check logs for SQL queries during characteristic operations.
  2. Dump Entities

    dd($characteristic->getValues()->toArray());
    
    • Verify relationships are loaded correctly.
  3. Check for Circular Dependencies

    • If characteristics load recursively (e.g., a characteristic has its own characteristics), use:
      $characteristic->setFetchValues(false); // Disable lazy loading
      

Extension Points

  1. Custom Value Types

    • Extend CharacteristicValue to add metadata (e.g., PriceRangeValue):
      class PriceRangeValue extends CharacteristicValue
      {
          private $minPrice;
          private $maxPrice;
      
          // Add getters/setters and Doctrine mappings
      }
      
  2. Validation Rules

    • Add constraints to Characteristic or CharacteristicValue:
      use Symfony\Component\Validator\Constraints as Assert;
      
      /**
       * @Assert\Length(max=100)
       */
      private $name;
      
  3. API Versioning

    • Override serializers to control API responses:
      class CharacteristicValueSerializer extends Serializer
      {
          public function serialize($value, $format, array $context = [])
          {
              return [
                  'id' => $value->getId(),
                  'label' => $value->getLabel(),
                  'v1' => $value->getSlug(), // Deprecated in v2
              ];
          }
      }
      
  4. Localization

    • Add translatable fields to Characteristic:
      use Gedmo\Translatable\Entity\TranslationInterface;
      
      /**
       * @ORM\OneToMany(targetEntity="Translation", mappedBy="object")
       */
      private $translations;
      
    • Configure Gedmo’s translation listener in services.yaml.
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware