Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inside a specific console command, we can not call an another command as a initialized instance of Command class. #51822

Closed
seriquynh opened this issue Jun 18, 2024 · 1 comment · Fixed by #51824
Assignees
Labels

Comments

@seriquynh
Copy link
Contributor

seriquynh commented Jun 18, 2024

Laravel Version

10.x

PHP Version

8.3

Database Driver & Version

No response

Description

Because of \Illuminate\Console\Command::call() method docblock, it must accept any kinds of Symfony Command instances. But it does not and raise an error.

    /**
     * Call another console command.
     *
     * @param  \Symfony\Component\Console\Command\Command|string  $command
     * @param  array  $arguments
     * @return int
     */
    public function call($command, array $arguments = [])
    {
        return $this->runCommand($command, $arguments, $this->output);
    }

Screenshot_4

Steps To Reproduce

  1. Inside a 10.x Laravel project, create a "demo" command like this:
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Foundation\Console\ViewClearCommand;

class DemoCommand extends Command
{
    protected $signature = 'demo';

    protected $description = 'This is "demo" command description';

    public function handle()
    {
        $this->call('view:clear'); // It works properly.

        $this->call(ViewClearCommand::class); // It works properly.

        $this->call(
            $this->laravel->make(ViewClearCommand::class) // It does not work and raise an error.
        );
    }
}
  1. Open the termial, go to the project directory and run "php artisan demo".
   INFO  Compiled views cleared successfully.

   INFO  Compiled views cleared successfully.


   TypeError

  class_exists(): Argument #1 ($class) must be of type string, Illuminate\Foundation\Console\ViewClearCommand given

  at vendor\laravel\framework\src\Illuminate\Console\Command.php:245
    241▕      * @return \Symfony\Component\Console\Command\Command
    242▕      */
    243▕     protected function resolveCommand($command)
    244▕     {
  ➜ 245▕         if (! class_exists($command)) {
    246▕             return $this->getApplication()->find($command);
    247▕         }
    248▕
    249▕         $command = $this->laravel->make($command);

  1   vendor\laravel\framework\src\Illuminate\Console\Command.php:245

  2   vendor\laravel\framework\src\Illuminate\Console\Concerns\CallsCommands.php:67
      Illuminate\Console\Command::resolveCommand(Object(Illuminate\Foundation\Console\ViewClearCommand))

When we pass a Command instance through call method, it continues passing through resolveCommand method. There, class_exists requires a string as the first parameter and an error is raised here.

We should either update call method to accept string only or update checks inside resolveCommand.

@crynobone
Copy link
Member

PR has been merged and pending next release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
2 participants