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

Easy Common Bundle Laravel Package

agence-adeliom/easy-common-bundle

Symfony bundle providing common utilities for EasyAdmin: reusable Doctrine entity traits (ID, slug, timestamps, soft delete, publish/status) and a PHP 8 enum polyfill/helper with static constructors, validation, and typed enum parameters.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require agence-adeliom/easy-common-bundle
    

    Ensure your config/bundles.php includes:

    return [
        // ...
        AgenceAdeliom\EasyCommonBundle\EasyCommonBundle::class => ['all' => true],
    ];
    
  2. First Use Case: Add a trait to an EasyAdmin entity (e.g., src/Entity/Post.php):

    use AgenceAdeliom\EasyCommonBundle\Entity\Traits\EntityIdTrait;
    use AgenceAdeliom\EasyCommonBundle\Entity\Traits\EntityTimestampableTrait;
    
    class Post extends BaseEntity
    {
        use EntityIdTrait;
        use EntityTimestampableTrait;
    }
    
  3. Verify Database Migration: Run php bin/console make:migration to generate fields for id, created_at, updated_at (if using TimestampableTrait).


Implementation Patterns

Common Workflows

1. Standardizing Entities with Traits

  • Use Case: Apply reusable traits to all EasyAdmin entities (e.g., EntityIdTrait, EntityTimestampableTrait).
  • Pattern:
    // BaseEntity.php (abstract)
    abstract class BaseEntity
    {
        use EntityIdTrait;
        use EntityTimestampableTrait;
    }
    
    Extend BaseEntity for all models to enforce consistency.

2. Enum Handling in EasyAdmin

  • Use Case: Define enums for status fields (e.g., published, draft).
  • Pattern:
    use AgenceAdeliom\EasyCommonBundle\Enum\Enum;
    
    class PostStatus extends Enum
    {
        public const DRAFT = 'draft';
        public const PUBLISHED = 'published';
    }
    
    Use in EntityStatusTrait:
    use EntityStatusTrait;
    
    class Post extends BaseEntity
    {
        use EntityStatusTrait;
    
        protected string $statusField = 'status';
        protected string $statusEnum = PostStatus::class;
    }
    

3. Soft Deletes with EasyAdmin

  • Use Case: Enable soft deletes for CRUD operations.
  • Pattern:
    use EntitySoftDeletableTrait;
    
    class Post extends BaseEntity
    {
        use EntitySoftDeletableTrait;
    
        protected string $deletedAtField = 'deleted_at';
    }
    
    Configure EasyAdmin CRUD:
    ->setEntityClass(Post::class)
    ->setDefaultSort(['id' => 'DESC'])
    ->ignoreSoftDeleted()
    

4. Slug Generation

  • Use Case: Auto-generate slugs from name fields.
  • Pattern:
    use EntityNameSlugTrait;
    
    class Post extends BaseEntity
    {
        use EntityNameSlugTrait;
    
        protected string $nameField = 'title';
        protected string $slugField = 'slug';
    }
    
    Add to EasyAdmin CRUD:
    ->setFormOptions([
        'validation_groups' => function (Post $post) {
            return ['Default', 'slug'];
        },
    ])
    

Integration Tips

EasyAdmin CRUD Configuration

  • Filtering Soft-Deleted Entities:

    ->setDefaultSort(['deleted_at' => 'ASC'])
    ->setFilterOptions([
        'deleted_at' => Filter\BooleanFilter::new()->setLabel('Deleted'),
    ])
    
  • Enum Dropdown in Forms:

    ->setFormOptions([
        'fields' => [
            'status' => Form\ChoiceType::new()
                ->setChoices(PostStatus::toArray())
                ->setPlaceholder('Select status'),
        ],
    ])
    

Validation

  • Slug Uniqueness:
    use Symfony\Component\Validator\Constraints as Assert;
    
    class Post extends BaseEntity
    {
        #[Assert\Unique(entityManager: 'doctrine', message: 'Slug already exists')]
        protected ?string $slug = null;
    }
    

Gotchas and Tips

Pitfalls

  1. PHP Version Mismatch:

    • Issue: Using 3.x with PHP < 8.2 or Symfony < 6.4.
    • Fix: Pin the correct branch in composer.json:
      "require": {
          "agence-adeliom/easy-common-bundle": "^2.x"
      }
      
  2. Trait Conflicts:

    • Issue: Overlapping methods (e.g., getId() in EntityIdTrait vs. custom id property).
    • Fix: Explicitly define property types:
      #[ORM\Id]
      #[ORM\GeneratedValue]
      #[ORM\Column(type: 'integer')]
      private ?int $id = null;
      
  3. Enum Polyfill:

    • Issue: PHP 8.1+ users may not need the polyfill.
    • Fix: Remove use AgenceAdeliom\EasyCommonBundle\Enum\Enum; if using native enums.
  4. Soft Deletes in Queries:

    • Issue: Forgetting to scope queries to exclude soft-deleted records.
    • Fix: Use ignoreSoftDeleted() in CRUD or manually scope:
      $posts = $entityManager->getRepository(Post::class)
          ->findBy([], [], null, null, ['deleted_at' => 'ASC']);
      

Debugging

  • Missing Fields in Migration:

    • Debug: Check if traits are applied to the entity class. Run:
      php bin/console doctrine:schema:validate
      
  • Enum Values Not Showing:

    • Debug: Verify the enum class is correctly referenced in statusEnum:
      protected string $statusEnum = PostStatus::class; // Must match namespace
      

Extension Points

  1. Customizing Slug Generation:

    • Override generateSlug() in EntityNameSlugTrait:
      public function generateSlug(): string
      {
          return strtolower(parent::generateSlug()) . '-custom';
      }
      
  2. Adding Custom Statuses:

    • Extend EntityStatusTrait:
      use EntityStatusTrait;
      
      class Post extends BaseEntity
      {
          use EntityStatusTrait;
      
          public function getStatusOptions(): array
          {
              return [
                  'draft' => 'Draft',
                  'published' => 'Published',
                  'archived' => 'Archived', // Custom
              ];
          }
      }
      
  3. Timestamp Precision:

    • Modify EntityTimestampableTrait to use DateTimeImmutable:
      #[ORM\Column(type: 'datetime_immutable')]
      private ?\DateTimeImmutable $updatedAt = null;
      

Configuration Quirks

  • EasyAdmin Version Compatibility:

    • Test with EasyAdmin 4.x/5.x. Some CRUD methods may differ (e.g., setFilterOptions vs. setFilters).
  • Doctrine Event Listeners:

    • If using EntityTimestampableTrait, ensure prePersist/preUpdate listeners are not duplicated in your entity.
  • Slug Collisions:

    • Handle collisions in generateSlug():
      public function generateSlug(): string
      {
          $slug = strtolower($this->name);
          $originalSlug = $slug;
          $count = 1;
      
          while ($this->repository->findOneBy(['slug' => $slug])) {
              $slug = "{$originalSlug}-{$count}";
              $count++;
          }
          return $slug;
      }
      
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