Weave 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

Command Scheduler Laravel Package

neogen/command-scheduler

Schedule and manage Laravel Artisan commands dynamically without touching your console kernel. Define commands, intervals, and arguments in config or the database, then let the scheduler run and track them automatically.

View on GitHub
Deep Wiki
Context7

Getting Started

Before anything else: this is a Symfony bundle, not a Laravel package. There is no service provider, no facade, no config/*.php file that Laravel's container will auto-discover. You will be manually wiring it or wrapping it.

  1. Read the repo first, in this order: composer.json (check the symfony/* version constraints — this tells you immediately whether it will even install alongside a modern Laravel), src/DependencyInjection/*Extension.php (the real config schema), src/Command/* (what actually executes), and any Resources/config/services.xml (how services are constructed and what they depend on).
  2. Install: composer require neogen/command-scheduler. Expect a conflict wall. If it pins symfony/console:^3.4|^4.0, Composer will refuse to install it beside a current Laravel (which requires Symfony 6/7 components). You may need --ignore-platform-reqs plus a fork, or to vendor the source into app/Support/CommandScheduler.
  3. First use case that actually works: run the bundle's Symfony Application in isolation from a scheduled Artisan command. Create app/Console/Commands/RunNeogenSchedule.php whose handle() boots a bare Symfony Application, registers the bundle's commands, and invokes them. Then schedule that one command in routes/console.php. This keeps the bundle's DB-monitoring logic intact while letting Laravel own the cron entrypoint.
  4. Verify before you build: php artisan tinker → confirm the classes autoload, then check the bundle's migration/schema requirements (if it tracks executions, it needs a table — and it will ship a Doctrine migration, not a Laravel one).

Realistically, evaluate this for 30 minutes and then decide whether the monitoring value justifies the glue. For most Laravel apps it does not — see the alternatives in the last section.

Implementation Patterns

Pattern 1 — Bare Symfony Application bridge (most viable). Wrap the bundle inside a single Artisan command. Build a Symfony\Component\Console\Application, register the bundle's command classes by hand, set the input, and return the exit code. Because you control the Application, you sidestep Symfony's kernel/bundle boot entirely — you only need the command classes and whatever services they touch. Inject those services manually from Laravel's container.

Pattern 2 — Cron wrapper with history table. If the bundle's value is the execution log, skip its scheduler and use only its model/repository. Migrate the schema with a hand-written Laravel migration mirroring the Doctrine entity, then write your own CommandRun Eloquent model against the same table. You get the monitoring data without the Symfony plumbing.

Pattern 3 — Laravel scheduler as orchestrator, package as recorder. Keep Schedule::command(...)->everyFiveMinutes() doing the actual dispatch, and record start/finish/exit-code rows around each invocation using the package's column shape. This gives you a clean upgrade path: today it writes to the package's table, tomorrow you swap in spatie/laravel-schedule-monitor without touching call sites.

Pattern 4 — Isolated subprocess. Shell out: Process::run('php bin/console neogen:run --quiet'). Ugly, but it is the only pattern guaranteed to work regardless of framework-version drift, and it isolates a 2018-era dependency from your app's autoloader and PHP version.

Integration tips

  • Register the bridge command as ->withoutOverlapping() and ->onOneServer() in Laravel's scheduler so the bundle's own lock (if any) is a second line of defence, not the first.
  • Capture and log exit codes yourself; the bundle's monitoring is only as good as the process exit status it observes, and Symfony console exit codes are not always what you expect from wrapped Artisan commands.
  • If you fork, tag it ("repositories" with a VCS entry in composer.json) rather than committing into vendor/, and pin the commit hash.

Gotchas and Tips

  • It is effectively unmaintained. Last release 2018-05-02, zero stars, zero dependents. There is no issue tracker activity to lean on, no security patch stream, and no PHP 8 compatibility guarantee. Treat it as source code you are adopting, not a dependency you are consuming.
  • PHP version drift is the first blocker. 2018-era code commonly uses createMock, each() on collections, or nullable-typehint syntax that breaks on PHP 8. Check for each(), dynamic properties, and ReflectionParameter::getClass() before committing.
  • Symfony-version drift is the second. Symfony 3/4 bundles assume ContainerAwareCommand (removed in Symfony 5) and bundle registration via AppKernel. Neither exists in a Laravel app. Anything extending ContainerAwareCommand must be rewritten or booted inside a real Symfony kernel.
  • Config is Symfony-style, not Laravel-style. The extension class defines the schema (->scalarNode('...'), ->arrayNode('...')). Read it rather than guessing key names from the README — the README is from 2018 and likely lags the code.
  • No Laravel migrations ship with it. Any Doctrine entity needs a hand-translated migration. Watch for datetime vs timestamp defaults and for indexes on the "last run" column that your monitoring queries will depend on.
  • Overlap protection is the classic failure mode. If the bundle does not implement locking, two cron ticks will double-run long commands. Add withoutOverlapping() at the Laravel scheduler layer regardless.
  • Debugging: since there is no service provider, php artisan about tells you nothing. Debug by instantiating the command class directly in tinker and calling execute() with an ArrayInput. Errors surface as raw Symfony exceptions with no Laravel context — wrap the bridge in try/catch and log with report().
  • Extension points are minimal. Without an event dispatcher wired to Laravel's, there is no clean hook. Your extension point is the bridge command: subclass it, override handle(), and emit your own Laravel events around the call.
  • Strongly consider not using it. Laravel's native scheduler already gives you withoutOverlapping(), onOneServer(), runInBackground(), before()/after()/onSuccess()/onFailure() hooks, and Schedule::command()->emailOutputOnFailure(). For the monitoring half, spatie/laravel-schedule-monitor is maintained, first-class Laravel, and stores run history. This package solves a problem Laravel solved in the box — the only reason to adopt it is if you are porting an existing Symfony app and want to preserve its operational behaviour verbatim.
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core