Skip to content

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

New issue

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

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

Already on GitHub? # to your account

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 crynobone added the bug label Jun 18, 2024
@crynobone crynobone self-assigned this Jun 18, 2024
crynobone added a commit that referenced this issue Jun 18, 2024
… of `Command` class.

fixes #51822

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>
taylorotwell pushed a commit that referenced this issue Jun 18, 2024
… of `Command` class. (#51824)

fixes #51822

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>
@crynobone
Copy link
Member

PR has been merged and pending next release

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