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

Sonata Timeline Bundle Laravel Package

awaresoft/sonata-timeline-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation via Composer (if not symlinked):

    composer require awaresoft/sonata-timeline-bundle
    

    Note: For local development, follow the README’s symlink instructions instead.

  2. Enable the Bundle in config/bundles.php:

    return [
        // ...
        Awaresoft\SonataTimelineBundle\SonataTimelineBundle::class => ['all' => true],
    ];
    
  3. Basic Configuration in config/packages/sonata_timeline.yaml:

    sonata_timeline:
        driver: doctrine_orm  # or 'doctrine_mongodb'
        model_manager: default
        models:
            event: App\Entity\Event
            timeline: App\Entity\Timeline
    
  4. Create Entities (if using Doctrine):

    php bin/console make:entity Event
    php bin/console make:entity Timeline
    

    Extend SonataTimelineBundle\Model\EventInterface and TimelineInterface in your entities.

  5. First Use Case:

    // In a controller/service
    $timeline = $this->getDoctrine()->getRepository(Timeline::class)->findOneBy(['slug' => 'project-x']);
    $events = $timeline->getEvents()->toArray(); // Load events for the timeline
    

Implementation Patterns

Core Workflows

1. Event Management

  • Creating Events:

    $event = new Event();
    $event->setTitle('Project Kickoff')
          ->setStartDate(new \DateTime('2023-10-01'))
          ->setEndDate(new \DateTime('2023-10-07'))
          ->setTimeline($timeline);
    $entityManager->persist($event);
    $entityManager->flush();
    
  • Bulk Operations: Use SonataTimelineBundle\Manager\EventManager to batch-create/update events:

    $eventManager = $this->container->get('sonata.timeline.manager.event');
    $eventManager->createMultiple($eventsArray, $timeline);
    

2. Timeline Views

  • Embedding in Twig:

    {% render timeline(timeline, {
        'height': '600px',
        'zoomable': true,
        'editable': current_user.can_edit
    }) %}
    

    Requires JavaScript initialization (see SonataAdminBundle for similar patterns).

  • Customizing Renders: Override the default template at templates/sonata_timeline/default/index.html.twig.

3. Integration with SonataAdmin

  • Admin Configuration:
    # config/packages/sonata_admin.yaml
    sonata_admin:
        options:
            timeline:
                enabled: true
                manager_type: sonata.timeline.manager.event
    
    Expose Event and Timeline as admin entities for CRUD.

4. Data Synchronization

  • Event Listeners:
    // src/EventListener/TimelineSyncListener.php
    class TimelineSyncListener implements EventSubscriberInterface
    {
        public static function getSubscribedEvents()
        {
            return [
                KernelEvents::VIEW => ['onKernelView', 20],
            ];
        }
    
        public function onKernelView(GetResponseForControllerResultEvent $event)
        {
            $timeline = $event->getControllerResult();
            if ($timeline instanceof Timeline) {
                $event->getRequest()->attributes->set('sonata_timeline_data', $timeline->getEvents());
            }
        }
    }
    

Integration Tips

  1. Doctrine vs. MongoDB:

    • For MongoDB, ensure your Timeline and Event entities implement SonataTimelineBundle\Model\MongoDB\TimelineInterface and EventInterface.
    • Use sonata.timeline.manager.mongodb_event as the manager service.
  2. Custom Event Types:

    • Extend SonataTimelineBundle\Model\Event and override getType():
      class CustomEvent extends Event
      {
          public function getType(): string
          {
              return 'custom';
          }
      }
      
    • Register the type in Twig:
      {% set timelineTypes = {
          'custom': {
              'label': 'Custom Event',
              'color': '#FF5733'
          }
      } %}
      
  3. API Exposure:

    • Use Symfony’s Serializer to expose timelines:
      $serializer = $this->container->get('serializer');
      $timelineData = $serializer->serialize($timeline, 'json', [
          'attributes' => ['groups' => ['timeline']],
      ]);
      
  4. Caching:

    • Cache timeline data with tags:
      $cache = $this->container->get('cache.app');
      $cache->set('timeline_' . $timeline->getId(), $events, 3600, ['timeline_' . $timeline->getId()]);
      

Gotchas and Tips

Pitfalls

  1. Symlinking Issues:

    • If symlinked, ensure composer dump-autoload is run after modifying the bundle.
    • Clear cache after symlink changes:
      php bin/console cache:clear
      php bin/console cache:pool:clear cache.array
      
  2. Doctrine Proxy Problems:

    • Lazy-loaded events may cause Undefined index: id errors. Use ->toArray() or ->getValues() to materialize collections:
      $events = $timeline->getEvents()->toArray(); // Force initialization
      
  3. JavaScript Dependencies:

    • The bundle relies on SonataAdmin’s timeline.js. Ensure it’s loaded:
      {{ parent() }}
      {{ sonata_timeline_js() }} {# Add this in your base template #}
      
  4. Timezone Handling:

    • Events use the system timezone by default. Normalize dates in your entities:
      $event->setStartDate($date->setTimezone(new \DateTimeZone('UTC')));
      
  5. Backward Compatibility:

    • Avoid extending SonataTimelineBundle\Model\Event directly in production. Use composition or interfaces instead.

Debugging

  1. Enable Debug Mode:

    # config/packages/dev/sonata_timeline.yaml
    sonata_timeline:
        debug: true
    

    Logs SQL queries and event lifecycle hooks.

  2. Common Errors:

    • "No manager found": Verify sonata_timeline.manager.event is autowired or configured in services.yaml.
    • Blank Timeline: Check if getEvents() returns a non-empty collection and the Twig template is rendered.
  3. Database Schema:

    • Run migrations after entity changes:
      php bin/console doctrine:migrations:diff
      php bin/console doctrine:migrations:migrate
      

Extension Points

  1. Custom Event Renderers:

    • Override SonataTimelineBundle\Twig\TimelineExtension:
      // src/Twig/AppTimelineExtension.php
      class AppTimelineExtension extends TimelineExtension
      {
          public function getEventTemplate(EventInterface $event)
          {
              return 'custom_timeline/event_' . $event->getType() . '.html.twig';
          }
      }
      
    • Register the extension in services.yaml:
      services:
          App\Twig\AppTimelineExtension:
              tags: ['twig.extension']
              arguments: ['@sonata.timeline.manager.event']
      
  2. Event Validation:

    • Add constraints to your Event entity:
      use Symfony\Component\Validator\Constraints as Assert;
      
      class Event
      {
          /**
           * @Assert\NotBlank
           * @Assert\Length(min=3)
           */
          private $title;
      }
      
  3. Event Subscribers:

    • Listen to sonata.timeline.event.pre_persist and sonata.timeline.event.pre_remove:
      $eventDispatcher->addListener(
          'sonata.timeline.event.pre_persist',
          function (Event $event) {
              $event->setCreatedAt(new \DateTime());
          }
      );
      
  4. Custom Timeline Providers:

    • Implement SonataTimelineBundle\Provider\TimelineProviderInterface for dynamic timeline generation:
      class DynamicTimelineProvider implements TimelineProviderInterface
      {
          public function getTimeline(string $slug): ?Timeline
          {
              // Fetch from API/database
          }
      }
      
    • Register in services.yaml:
      sonata.timeline.provider.dynamic:
          class: App\Provider\DynamicTimelineProvider
          tags: ['sonata.timeline.provider']
      
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
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