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

Symfony Schedule Bundle Laravel Package

dbh/symfony-schedule-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require dbh/symfony-schedule-bundle
    

    Ensure Dbh\Symfony\ScheduleBundle\DbhScheduleBundle is enabled in config/bundles.php.

  2. Create a Schedule Manager Implement ManagerInterface in src/Model/ScheduleManager.php:

    namespace App\Model;
    
    use Dbh\Symfony\ScheduleBundle\Model\ManagerInterface;
    use Dbh\Symfony\ScheduleBundle\Model\Schedule;
    
    class ScheduleManager implements ManagerInterface {
        public function schedule(Schedule $schedule) {
            // Define your cron jobs here
        }
    }
    
  3. Configure the Bundle Create config/packages/schedule.yaml:

    schedule:
        manager: App\Model\ScheduleManager
    
  4. Define a Command Create a console command (e.g., src/Command/TestCommand.php) and reference it in schedule():

    $schedule->command('app:test-command')->dailyAt('12:00');
    
  5. Run the Scheduler Add a cron entry in your server to execute:

    * * * * * php /path/to/bin/console schedule:run
    

Implementation Patterns

Workflows

  1. Defining Jobs Use the Schedule class to define cron jobs with Laravel-inspired syntax:

    $schedule->command('app:backup')->daily();
    $schedule->command('app:cleanup')->weeklyOn(1, '03:00'); // Every Monday at 3 AM
    $schedule->command('app:report')->cron('0 9 * * 1-5'); // Custom cron expression
    
  2. Chaining Methods Chain methods for readability:

    $schedule->command('app:send-reminders')
        ->at('08:00')
        ->onWeekdays();
    
  3. Environment-Specific Scheduling Use Symfony’s environment-aware services to conditionally schedule jobs:

    if ($this->get('kernel')->getEnvironment() === 'prod') {
        $schedule->command('app:monitor')->everyFiveMinutes();
    }
    
  4. Dynamic Scheduling Inject dependencies (e.g., services) into ScheduleManager to dynamically configure jobs:

    public function __construct(private SomeService $service) {}
    
    public function schedule(Schedule $schedule) {
        $schedule->command('app:process-' . $this->service->getQueue())
            ->hourly();
    }
    
  5. Logging and Monitoring Extend ScheduleManager to log job executions or integrate with Symfony’s Monolog:

    use Psr\Log\LoggerInterface;
    
    public function __construct(private LoggerInterface $logger) {}
    
    public function schedule(Schedule $schedule) {
        $schedule->command('app:log-test')->daily();
        // Log job registration
        $this->logger->info('Scheduled log-test command daily');
    }
    
  6. Testing Schedules Mock Schedule in PHPUnit tests to verify job configurations:

    $schedule = $this->createMock(Schedule::class);
    $manager = new ScheduleManager();
    $manager->schedule($schedule);
    $this->assertEquals('app:test-command', $schedule->expects()->command('app:test-command'));
    

Gotchas and Tips

Pitfalls

  1. Cron Syntax Errors

    • Issue: Incorrect cron expressions (e.g., cron('0 9 * * *') with invalid time) may cause silent failures.
    • Fix: Validate expressions using tools like crontab.guru or Symfony’s CronExpression.
  2. Missing schedule:run Command

    • Issue: Forgetting to add the cron entry to execute schedule:run will prevent jobs from triggering.
    • Fix: Add to crontab:
      * * * * * cd /path/to/project && php bin/console schedule:run >> /dev/null 2>&1
      
  3. Command Not Found

    • Issue: Referencing a non-existent command (e.g., app:nonexistent) throws an error during schedule:run.
    • Fix: Ensure commands are registered in config/services.yaml or autoloaded.
  4. Timezone Mismatches

    • Issue: Jobs may run at unexpected times if the server’s timezone differs from the schedule’s timezone.
    • Fix: Set the timezone in ScheduleManager:
      DateTime::setTimezone(new DateTimeZone('Europe/Warsaw'));
      
  5. Overwriting Configurations

    • Issue: Multiple schedule.yaml files or bundle overrides may conflict.
    • Fix: Use imports in config/packages/schedule.yaml to merge configurations:
      imports:
          - { resource: schedule/local.yaml }
          - { resource: schedule/prod.yaml }
      

Tips

  1. Use Descriptive Command Names Prefix commands with a namespace (e.g., app:backup-database) to avoid conflicts and improve clarity.

  2. Leverage Symfony’s Dependency Injection Inject services into ScheduleManager to dynamically fetch job configurations:

    public function schedule(Schedule $schedule) {
        $config = $this->configService->get('schedule');
        foreach ($config['jobs'] as $job) {
            $schedule->command($job['command'])->{$job['frequency']}();
        }
    }
    
  3. Extend Schedule Class Add custom methods to Schedule for project-specific needs (e.g., everyBusinessHour()):

    // In a custom Schedule class
    public function everyBusinessHour() {
        return $this->cron('0 9-17 * * 1-5'); // 9 AM to 5 PM, Mon-Fri
    }
    
  4. Debugging Job Execution Use Symfony’s debug:schedule command (if available) or log job triggers:

    $schedule->command('app:debug')->dailyAt('00:00')->description('Debug logs');
    
  5. Handle Job Failures Implement retry logic or notifications in commands. Example:

    // In app/Command/TestCommand.php
    protected function execute(InputInterface $input, OutputInterface $output) {
        try {
            // Job logic
        } catch (\Exception $e) {
            $this->logger->error('Job failed', ['error' => $e->getMessage()]);
            throw $e; // Let Symfony handle it or add custom logic
        }
    }
    
  6. Environment-Specific Schedules Use Symfony’s %kernel.environment% parameter to load different schedules:

    # config/packages/schedule.yaml
    schedule:
        manager: App\Model\ScheduleManager
        environment: '%kernel.environment%'
    

    Then conditionally load jobs in ScheduleManager:

    if ($this->environment === 'prod') {
        $schedule->command('app:prod-task')->hourly();
    }
    
  7. Avoid Hardcoding Paths Use Symfony’s bin/console path (e.g., php bin/console) in cron entries instead of absolute paths to ensure portability.

  8. Monitor Job Logs Redirect schedule:run output to a log file for auditing:

    * * * * * php bin/console schedule:run >> var/log/schedule.log 2>&1
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope