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

Ids Laravel Package

digital-craftsman/ids

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require digital-craftsman/ids
    

    Ensure PHP 8.4+ is used (or 8.5+ for latest features).

  2. First Use Case: Define an ID value object for your entity:

    use DigitalCraftsman\Ids\Id;
    
    class UserId extends Id {}
    

    Now use it in your entity:

    class User
    {
        private UserId $id;
    
        public function __construct(UserId $id)
        {
            $this->id = $id;
        }
    }
    
  3. Key Classes to Explore:

    • Id (base class for all IDs)
    • IdList (for collections of IDs)
    • Doctrine\DBAL\Types\IdType (for database storage)
    • Doctrine\DBAL\Types\IdListType (for database storage of lists)

Implementation Patterns

Core Workflows

  1. Entity Design: Replace primitive string/int IDs with typed value objects:

    class Order
    {
        private OrderId $id;
        private OrderId $parentOrderId;
        private OrderId[] $relatedOrders;
    
        public function __construct(OrderId $id)
        {
            $this->id = $id;
        }
    }
    
  2. Database Integration: Use Doctrine DBAL types for seamless storage:

    # config/packages/doctrine.yaml
    doctrine:
        dbal:
            types:
                id: DigitalCraftsman\Ids\Doctrine\DBAL\Types\IdType
                id_list: DigitalCraftsman\Ids\Doctrine\DBAL\Types\IdListType
    

    Then annotate entity properties:

    use Doctrine\DBAL\Types\Types;
    
    class Order
    {
        #[ORM\Column(type: Types::ID)]
        private OrderId $id;
    }
    
  3. API/Serialization: Leverages Symfony’s normalizers for automatic conversion:

    // Request/Response
    {
        "id": "550e8400-e29b-41d4-a716-446655440000"
    }
    

    No manual casting needed—works with:

    • JSON API
    • XML
    • Form data
    • Query parameters
  4. UUID Generation: Prefer the PHP uuid extension for performance:

    $id = new UserId(); // Auto-generates UUID
    

    Fallback to symfony/polyfill-uuid if extension is unavailable.


Integration Tips

  1. Custom ID Formats: Extend Id for non-UUID formats (e.g., ULIDs, integers):

    class CustomId extends Id
    {
        protected static function generate(): string
        {
            return (string) random_int(1, PHP_INT_MAX);
        }
    }
    
  2. Validation: Use built-in validation (e.g., UUIDv4 format):

    use Symfony\Component\Validator\Constraints as Assert;
    
    class UserId extends Id
    {
        #[Assert\Type('DigitalCraftsman\Ids\Id')]
        public function __toString(): string
        {
            return $this->value;
        }
    }
    
  3. Query Building: Use IdList for IN clauses:

    $ids = new IdList([new UserId('1'), new UserId('2')]);
    $qb->andWhere('u.id IN (:ids)')
       ->setParameter('ids', $ids->toArray());
    
  4. Testing: Mock IDs easily:

    $mockId = new UserId('fixed-uuid-for-testing');
    $user = new User($mockId);
    

Gotchas and Tips

Pitfalls

  1. Doctrine ORM Caching:

    • Clear cache after adding new DBAL types:
      php bin/console doctrine:cache:clear-metadata
      php bin/console doctrine:cache:clear-query
      php bin/console doctrine:cache:clear-result
      
  2. UUID Extension Conflict:

    • If using ramsey/uuid, ensure no version conflicts (both packages may use uuid namespace).
    • Prefer digital-craftsman/ids’s UUID logic over ramsey/uuid to avoid duplication.
  3. Serialization Edge Cases:

    • Custom serializers may break normalization. Stick to Symfony’s default unless extending.
    • Avoid circular references in DTOs with IDs (use #[Groups] in API Platform).
  4. Database Portability:

    • UUIDs work across databases, but some (e.g., MySQL) require BINARY(16) for optimal indexing.
    • Configure IdType’s uuidType in Doctrine:
      doctrine:
          dbal:
              types:
                  id:
                      uuid_type: 'binary(16)'
      

Debugging Tips

  1. Validation Errors:

    • Check if IDs are properly typed (e.g., new UserId('invalid') throws InvalidArgumentException).
    • Use Id::isValid() for manual checks:
      if (!UserId::isValid('not-a-uuid')) {
          throw new \InvalidArgumentException('Invalid ID format');
      }
      
  2. Doctrine Mappings:

    • Verify Types::ID is correctly mapped in entity metadata:
      $metadata->mapField([
          'fieldName' => 'id',
          'type' => 'id',
      ]);
      
  3. Performance:

    • Profile UUID generation with/without the PHP extension:
      $start = microtime(true);
      for ($i = 0; $i < 1000; $i++) {
          $id = new UserId();
      }
      echo microtime(true) - $start; // Compare with/without extension
      

Extension Points

  1. Custom Normalizers: Override Symfony’s normalizers for custom formats:

    use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
    
    class CustomIdDenormalizer implements DenormalizerInterface
    {
        public function denormalize($data, string $type, string $format, array $context)
        {
            return new $type($data); // Custom logic here
        }
        // ...
    }
    

    Register via Symfony’s serializer.normalizers service tag.

  2. Event Listeners: Add logic on ID generation/validation:

    use DigitalCraftsman\Ids\Event\IdGeneratedEvent;
    
    $dispatcher->addListener(IdGeneratedEvent::class, function (IdGeneratedEvent $event) {
        // Log or audit ID creation
    });
    
  3. Doctrine Lifecycle Callbacks: Use prePersist/preUpdate to validate IDs:

    use Doctrine\ORM\Mapping as ORM;
    
    #[ORM\Entity]
    class Order
    {
        #[ORM\PrePersist]
        public function validateId(): void
        {
            if (!$this->id->isValid()) {
                throw new \RuntimeException('Invalid ID');
            }
        }
    }
    
  4. API Platform: Customize ID output in collections:

    # config/api_platform/resources.yaml
    resources:
        App\Entity\User:
            collectionOperations:
                get:
                    normalization_context:
                        groups: ['user:read']
                    denormalization_context:
                        groups: ['user:write']
    
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.
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver