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

Message Bundle Laravel Package

braune-digital/message-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require braune-digital/message-bundle
    

    Enable the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 2/3):

    BrauneDigital\MessageBundle\BrauneDigitalMessageBundle::class => ['all' => true],
    
  2. Generate Extensions (Critical for customization):

    php bin/console sonata:easy-extends:generate --dest=src BrauneDigitalMessageBundle
    

    Enable the generated bundle in config/bundles.php:

    Application\BrauneDigital\MessageBundle\ApplicationBrauneDigitalMessageBundle::class => ['all' => true],
    
  3. Extend User Entity: Add the required relations to your User entity (XML/YAML/Annotation). Example snippet:

    <one-to-many target-entity="Application\BrauneDigital\MessageBundle\Entity\UserHasConversation" field="conversations" mapped-by="user">
        <cascade><cascade-remove /></cascade>
        <order-by>
            <order-by-field name="joinedOn" direction="DESC"/>
        </order-by>
    </one-to-many>
    
  4. First Use Case: Create a conversation between two users via a controller:

    use BrauneDigital\MessageBundle\Entity\Conversation;
    use BrauneDigital\MessageBundle\Entity\Message;
    
    $conversation = new Conversation();
    $conversation->addUser($senderUser);
    $conversation->addUser($recipientUser);
    $entityManager->persist($conversation);
    
    $message = new Message();
    $message->setConversation($conversation);
    $message->setSender($senderUser);
    $message->setContent("Hello!");
    $entityManager->persist($message);
    $entityManager->flush();
    

Implementation Patterns

Core Workflows

  1. Conversation Management:

    • Create: Use Conversation entity with addUser() for participants.
    • Retrieve: Fetch via UserHasConversation (e.g., $user->getConversations()).
    • Mark as Read: Extend Message entity to add isRead flag and update via repository.
  2. Message Handling:

    • Send: Attach to a Conversation and set sender. Use MessageBundle's Message entity.
    • Threading: Group by conversation_id in queries. Example:
      $messages = $entityManager->getRepository(Message::class)
          ->findBy(['conversation' => $conversation], ['createdAt' => 'DESC']);
      
  3. Notifications:

    • Trigger events (e.g., message.sent) via Symfony's event dispatcher. Extend the bundle to listen:
      # config/services.yaml
      BrauneDigital\MessageBundle\EventListener\MessageListener:
          tags:
              - { name: kernel.event_listener, event: message.sent, method: onMessageSent }
      
  4. API Integration:

    • Expose endpoints for conversations/messages using Symfony's serializers:
      use Symfony\Component\Serializer\Annotation\Groups;
      
      class Message {
          /** @Groups({"api"}) */
          private $content;
      }
      

Integration Tips

  • Doctrine Lifecycle Callbacks: Use @ORM\PrePersist/@ORM\PostUpdate in extended entities to auto-set timestamps (e.g., createdAt).

    use Doctrine\ORM\Mapping as ORM;
    
    /** @ORM\PrePersist */
    public function setCreatedAtValue() {
        $this->createdAt = new \DateTime();
    }
    
  • Sonata Admin: Register Conversation/Message in services.yaml for admin panel:

    services:
        app.admin.conversation:
            class: Application\BrauneDigital\MessageBundle\Admin\ConversationAdmin
            tags:
                - { name: sonata.admin, manager_type: orm, group: "Messages", label: "Conversations" }
    
  • Testing: Use MessageBundle's entities in PHPUnit tests. Example:

    public function testMessageCreation() {
        $conversation = new Conversation();
        $conversation->addUser($this->createMock(User::class));
        $message = new Message();
        $message->setConversation($conversation);
        $this->assertEquals($conversation, $message->getConversation());
    }
    

Gotchas and Tips

Pitfalls

  1. SonataEasyExtends Dependency:

    • The bundle requires sonata-project/easy-extends for customization. Without it, you cannot extend entities.
    • Fix: Install via Composer:
      composer require sonata-project/easy-extends
      
  2. Entity Overrides:

    • Extending entities (e.g., Message) must be done via sonata:easy-extends:generate. Directly modifying original entities will break updates.
    • Tip: Use --dest to specify a custom namespace (e.g., src/Application/BrauneDigital/MessageBundle/Entity).
  3. Circular References:

    • The UserHasConversation/UserHasMessage entities create circular references. Configure Doctrine to handle them:
      <many-to-one target-entity="User" inversed-by="conversations">
          <join-column name="user_id" referenced-column-name="id" on-delete="CASCADE"/>
      </many-to-one>
      
  4. Outdated Symfony 2 Syntax:

    • The bundle assumes Symfony 2/3 conventions (e.g., AppKernel.php). For Symfony 4/5:
      • Use config/bundles.php instead of AppKernel.
      • Replace php app/console with php bin/console.
  5. Missing Default Routes:

    • The bundle does not include CRUD routes. You must manually define them in routing.yaml:
      braune_digital_message_conversation:
          path: /conversations
          controller: Application\BrauneDigital\MessageBundle\Controller\ConversationController::index
      

Debugging Tips

  1. Entity Mapping Issues:

    • Clear cache after extending entities:
      php bin/console cache:clear
      php bin/console doctrine:schema:update --force
      
  2. Event Dispatching:

    • Verify events are fired by adding a debug listener:
      public function onMessageSent(MessageEvent $event) {
          error_log("Message sent: " . $event->getMessage()->getContent());
      }
      
  3. Performance:

    • Lazy-load conversations/messages to avoid N+1 queries:
      $user->getConversations()->matching($qb->orderBy('joinedOn', 'DESC'))->setMaxResults(10);
      

Extension Points

  1. Custom Message Types:

    • Extend the Message entity to add fields (e.g., isSystemMessage, attachment):
      /** @ORM\Column(type="boolean") */
      private $isSystemMessage = false;
      
      /** @ORM\ManyToOne(targetEntity="Attachment") */
      private $attachment;
      
  2. Validation:

    • Add constraints to extended entities:
      use Symfony\Component\Validator\Constraints as Assert;
      
      /** @Assert\NotBlank */
      private $content;
      
  3. API Resources:

    • Create custom serializers for nested data (e.g., conversations with messages):
      class ConversationSerializer extends AbstractNormalizer {
          public function normalize($object, $format = null, array $context = []) {
              return [
                  'id' => $object->getId(),
                  'messages' => $object->getMessages()->map(fn($m) => $m->getContent()),
              ];
          }
      }
      
  4. WebSocket Integration:

    • Extend the bundle to push real-time updates. Example with Ratchet:
      // In MessageEventListener
      public function onMessageSent(MessageEvent $event) {
          $this->websocketClient->send(json_encode([
              'type' => 'message',
              'data' => $event->getMessage()->getContent(),
          ]));
      }
      
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.
croct/coding-standard
croct/plug-php
nqxcode/phpmorphy
boundwize/pyrameter
testo/facade
headercat/phpstan-extension-ide-helper
yosymfony/parser-utils
innmind/black-box
babenkoivan/elastic-migrations
babenkoivan/elastic-adapter
develia/commons
dmstr/symfony-system-resources-bundle
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
renatomarinho/laravel-page-speed
develia/geo-bundle
austinheap/laravel-database-encryption
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle