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

Attribute Laravel Package

sylius/attribute

Sylius Attribute component provides a flexible attribute system for PHP apps: define attribute types, store values, and attach them to resources. Used across Sylius to add custom fields and metadata with validation and persistence support.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require sylius/attribute
    

    Add to config/app.php under providers:

    Sylius\Component\Attribute\AttributeServiceProvider::class,
    
  2. Publish Config (Optional)

    php artisan vendor:publish --provider="Sylius\Component\Attribute\AttributeServiceProvider" --tag="sylius_attribute:config"
    

    Check config/sylius_attribute.php for default settings.

  3. First Use Case: Defining Attributes

    use Sylius\Component\Attribute\Model\AttributeInterface;
    use Sylius\Component\Attribute\Model\AttributeValueInterface;
    
    // Define an attribute (e.g., for a product)
    $attribute = new Attribute();
    $attribute->setType('string'); // or 'integer', 'boolean', 'float', 'datetime', 'json'
    $attribute->setCode('color');
    $attribute->setLabel('Color');
    
    // Save via Doctrine (if using Sylius' ORM integration)
    $em->persist($attribute);
    $em->flush();
    
  4. Key Classes to Know

    • Attribute – Represents a configurable property (e.g., "Size", "Weight").
    • AttributeValue – Stores the value of an attribute for a specific entity (e.g., a product’s "Size: M").
    • AttributeRepository – Fetches attributes by code/type.
    • AttributeService – Handles value validation and type casting.

Implementation Patterns

1. Attribute Assignment Workflow

For Products (or any entity):

// Assign an attribute value to an entity (e.g., Product)
$product = $productRepository->find(1);
$attribute = $attributeRepository->findOneBy(['code' => 'color']);

$attributeValue = new AttributeValue();
$attributeValue->setAttribute($attribute);
$attributeValue->setValue('red'); // Raw value (casted to type later)
$product->addAttributeValue($attributeValue);

$em->persist($product);
$em->flush();

Retrieving Values:

$color = $product->getAttributeValue('color')->getValue(); // Returns 'red' (string)

2. Type-Specific Handling

Use the AttributeService to validate/cast values:

$attributeService = $this->container->get('sylius_attribute.attribute_service');

// Validate and cast a value
$validatedValue = $attributeService->validateAndCastValue(
    $attribute,
    'blue', // raw input
    $product  // entity (optional, for context)
);

Supported Types:

  • string, integer, boolean, float, datetime (ISO-8601), json (array/object).

3. Dynamic Attribute Management

Check if an entity has an attribute:

if ($product->hasAttribute('color')) {
    $value = $product->getAttributeValue('color')->getValue();
}

Bulk Assignment (e.g., CSV import):

$data = [
    'color' => 'green',
    'size' => 'L',
    'weight' => 2.5,
];

foreach ($data as $code => $value) {
    $attribute = $attributeRepository->findOneBy(['code' => $code]);
    if ($attribute) {
        $product->addAttributeValue($attribute, $value);
    }
}

4. Integration with Forms

Use Sylius\Component\Attribute\Form\Type\AttributeType for Symfony forms:

use Sylius\Component\Attribute\Form\Type\AttributeType;

$builder->add('color', AttributeType::class, [
    'attribute' => $attributeRepository->findOneBy(['code' => 'color']),
    'required' => false,
]);

5. Event-Driven Extensions

Listen for attribute.value.set or attribute.value.removed events (if using Sylius’ event system):

$dispatcher->addListener(
    'attribute.value.set',
    function (AttributeValueEvent $event) {
        // Log or process changes
    }
);

Gotchas and Tips

Pitfalls

  1. Type Mismatches

    • Issue: Passing null or invalid data to validateAndCastValue() throws exceptions.
    • Fix: Always validate input before casting:
      try {
          $validated = $attributeService->validateAndCastValue($attribute, $rawValue);
      } catch (InvalidArgumentException $e) {
          // Handle error (e.g., show user feedback)
      }
      
  2. Circular References in JSON

    • Issue: Storing nested objects/arrays with circular references in json type attributes will break serialization.
    • Fix: Use json_encode() with JSON_THROW_ON_ERROR or flatten data.
  3. Doctrine Proxy Conflicts

    • Issue: If using Sylius’ ORM integration, ensure your entity extends Sylius\Component\Attribute\Model\AttributeSubjectInterface to avoid proxy issues.
    • Fix: Implement getAttributeValues() and addAttributeValue() methods.
  4. Attribute Code Uniqueness

    • Issue: Attribute codes (e.g., color) must be unique across the system. Duplicates cause EntityManager errors.
    • Fix: Add a unique constraint in your database schema or validate in code:
      $existing = $attributeRepository->findOneBy(['code' => 'color']);
      if ($existing && $existing->getId() !== $attribute->getId()) {
          throw new \RuntimeException('Attribute code "color" already exists.');
      }
      

Debugging Tips

  1. Check Raw Values Use getRawValue() to inspect uncasted data:

    $rawValue = $attributeValue->getRawValue(); // Bypasses type casting
    
  2. Enable Attribute Logging Add to config/sylius_attribute.php:

    'debug' => env('APP_DEBUG', false),
    

    Logs validation errors and casting steps.

  3. Database Schema Ensure your attribute_value table has:

    • value column (type: text for JSON, string for others).
    • type column (to store the attribute’s type).

Extension Points

  1. Custom Value Processors Override type casting logic by implementing Sylius\Component\Attribute\ValueProcessor\ValueProcessorInterface:

    class CustomJsonProcessor implements ValueProcessorInterface {
        public function process($value, AttributeInterface $attribute): ?string {
            // Custom JSON handling
            return json_encode($value, JSON_THROW_ON_ERROR);
        }
    }
    

    Register in config/sylius_attribute.php:

    'value_processors' => [
        'json' => App\CustomJsonProcessor::class,
    ],
    
  2. Attribute Filters Extend Sylius\Component\Attribute\Filter\AttributeFilter to add custom filtering logic (e.g., for search).

  3. Attribute Events Dispatch custom events for attribute changes:

    $dispatcher->dispatch(new AttributeUpdatedEvent($attribute, $oldValue, $newValue));
    

Performance Tips

  1. Cache Attribute Lookups Cache frequently accessed attributes by code:

    $attribute = Cache::remember("attribute_{$code}", 3600, function () use ($code) {
        return $attributeRepository->findOneBy(['code' => $code]);
    });
    
  2. Batch Attribute Value Updates Use Doctrine’s BATCH_SIZE for bulk operations:

    $em->getConnection()->getConfiguration()->setSQLLogger(null); // Disable logging
    $em->flush();
    $em->getConnection()->getConfiguration()->setSQLLogger($logger);
    
  3. Avoid N+1 Queries Eager-load attribute values:

    $products = $productRepository->findBy([], [
        'attributeValues' => ['attribute' => 'color']
    ]);
    
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.
craftcms/url-validator
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony