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

Web Command Bundle Laravel Package

danilovl/web-command-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require danilovl/web-command-bundle
    

    Add to config/bundles.php:

    Danilovl\WebCommandBundle\WebCommandBundle::class => ['all' => true],
    
  2. Configure (config/packages/web_command.yaml):

    web_command:
        api_prefix: 'api/commands'
        console_path: '%kernel.project_dir%/bin/console'
        async: true
        memory_limit: '512M'
        time_limit: 3600
    
  3. First Use Case:

    • Run a command via API:
      curl -X POST http://your-app/api/commands/run \
           -H "Content-Type: application/json" \
           -d '{"command": "cache:clear"}'
      
    • Check async status (if enabled):
      curl http://your-app/api/commands/status/{job_id}
      

Implementation Patterns

Core Workflows

  1. Synchronous Execution:

    • Directly invoke commands via API:
      $response = $client->request('POST', '/api/commands/run', [
          'json' => ['command' => 'app:generate:key']
      ]);
      
    • Useful for short-lived, non-blocking tasks (e.g., cache operations).
  2. Asynchronous Execution (Messenger):

    • Configure commands for async in config/packages/web_command.yaml:
      commands:
          'app:export:data':
              async: true
              voter: App\Voter\ExportVoter
      
    • Trigger via API and poll status:
      // Start job
      $jobId = $response->toArray()['job_id'];
      
      // Check status later
      $status = $client->get("/api/commands/status/{$jobId}");
      
  3. Parameterized Commands:

    • Define dynamic parameters in config:
      commands:
          'app:send:email':
              parameters:
                  - name: 'recipient'
                    type: 'string'
                    required: true
      
    • Pass parameters via API:
      {
          "command": "app:send:email",
          "parameters": {"recipient": "user@example.com"}
      }
      
  4. EasyAdmin Integration:

    • Enable dashboard in config/packages/easy_admin.yaml:
      easy_admin:
          entities:
              Danilovl\WebCommandBundle\Entity\Command:
                  class: Danilovl\WebCommandBundle\Entity\Command
                  list: [id, name, async, enabled]
      
    • Access at /admin/commands to manage allowed commands.

Integration Tips

  • Laravel-Specific:

    • Override Symfony’s ConsoleApplication in App\Kernel:
      use Danilovl\WebCommandBundle\Console\LaravelApplication;
      protected function createConsoleApplication(): LaravelApplication
      {
          return new LaravelApplication($this);
      }
      
    • Extend Command entity for custom fields (e.g., laravel_log_channel).
  • Authentication:

    • Secure endpoints with Laravel’s middleware:
      Route::middleware(['auth:sanctum'])->post('/api/commands/run');
      
  • Logging:

    • Redirect command output to Laravel’s log:
      web_command:
          logger: monolog
      

Gotchas and Tips

Pitfalls

  1. Async Configuration:

    • Forgetting to enable Messenger in config/packages/messenger.yaml:
      framework:
          messenger:
              transports:
                  async: '%env(MESSENGER_TRANSPORT_DSN)%'
      
    • Fix: Ensure web_command.async: true and Messenger is installed (composer require symfony/messenger).
  2. Command Whitelisting:

    • By default, only commands listed in config/packages/web_command.yaml under commands are allowed.
    • Fix: Explicitly whitelist commands or disable validation:
      web_command:
          validate_commands: false  # Use with caution!
      
  3. Memory/Time Limits:

    • Commands exceeding memory_limit or time_limit may fail silently.
    • Debug: Check var/log/web_command.log for execution errors.
  4. EasyAdmin Conflicts:

    • If EasyAdmin is not installed, the dashboard routes will 404.
    • Fix: Install EasyAdmin (composer require easycorp/easy-admin-bundle) or disable dashboard:
      web_command:
          dashboard: false
      

Debugging

  • API Errors:

    • Validate request payloads with:
      curl -v -X POST http://your-app/api/commands/run -d '...'
      
    • Check for 422 Unprocessable Entity (invalid parameters) or 403 Forbidden (missing voter).
  • Async Jobs:

    • Monitor failed jobs in Doctrine:
      SELECT * FROM web_command_job WHERE status = 'failed';
      
    • Replay failed jobs with:
      php bin/console messenger:retry-all
      

Extension Points

  1. Custom Voters:

    • Implement CommandVoterInterface to restrict access:
      use Danilovl\WebCommandBundle\Security\CommandVoterInterface;
      
      class AdminVoter implements CommandVoterInterface
      {
          public function supports(string $command, $subject): bool
          {
              return str_starts_with($command, 'app:admin:');
          }
      
          public function vote($subject, string $command, array $parameters): bool
          {
              return auth()->user()->isAdmin();
          }
      }
      
    • Register in config:
      commands:
          'app:admin:user:create':
              voter: App\Voter\AdminVoter
      
  2. Command History:

    • Extend Job entity to store custom metadata:
      // src/Entity/ExtendedJob.php
      use Danilovl\WebCommandBundle\Entity\Job;
      
      class ExtendedJob extends Job
      {
          #[ORM\Column(nullable: true)]
          private ?string $userAgent = null;
      }
      
    • Update Job repository to use your extended class.
  3. Webhooks:

    • Listen for job completion via Messenger’s failed/succeeded events:
      use Symfony\Component\Messenger\Event\WorkerFailedEvent;
      
      $eventDispatcher->addListener(WorkerFailedEvent::class, function (WorkerFailedEvent $event) {
          Log::error('Command failed', ['job' => $event->getEnvelope()->getMessage()]);
      });
      
  4. Laravel Artisan Proxy:

    • Override ConsoleApplication to support Laravel’s Artisan commands:
      use Danilovl\WebCommandBundle\Console\LaravelApplication;
      use Symfony\Component\Console\Application;
      
      class CustomApplication extends LaravelApplication
      {
          protected function getDefaultCommands(): array
          {
              return array_merge(parent::getDefaultCommands(), [
                  new \Artisan\Commands\MakeControllerCommand(),
              ]);
          }
      }
      
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
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