1

I'm trying to extend my Laravel Artisan commands with a trait. The trait should capture all command line output and send it to Slack.

I've got the 'send messages to slack' part working with this package.

However I'm failing to capture the console output. This is what I've got:

namespace App\Traits;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Output\OutputInterface;

trait NotifiesSlack
{
    /**
     * Execute the console command.
     *
     * @param  \Symfony\Component\Console\Input\InputInterface $input
     * @param  \Symfony\Component\Console\Output\OutputInterface $output
     * @return mixed
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $consoleOutput = new BufferedOutput;

        $call = $this->laravel->call([$this, 'handle']);

        $this->notifySlack($consoleOutput->fetch());

        return $call;
    }

    public function notifySlack(string $output)
    {
        \Slack::send($output);
    }
}

Am I overriding the right method? Are there other ways to capture the console output from the Command class?

Any help is welcome! Thanks in advance.

Martijn Imhoff
  • 918
  • 1
  • 8
  • 22
  • 1
    Why do you use a package for [something that is already included in the framework itself](https://laravel.com/docs/5.7/notifications#slack-notifications)? – Kyslik Nov 06 '18 at 10:51
  • Because it's functionality differs. The framework works with notifiable models. I'm not looking to notify a user or another model. I'm looking for a systeemwide admin-like message. – Martijn Imhoff Nov 06 '18 at 12:20
  • For that use [logs](https://laravel.com/docs/5.7/logging#configuration); with `slack` channel driver. Good luck! – Kyslik Nov 06 '18 at 14:07

1 Answers1

-1

You are experiencing usual case of not able to override method via trait. It's obviously because the execute method is already declared in the class itself rendering the trait useless.

A quick and easy way, is to simply create your own abstract command class that extends the Illuminate\Console\Command; and override the execute method to your liking; afterwards use the abstract command class for your slack-reportable commands as base.

abstract class NotifiesSlackCommand extend Illuminate\Console\Command {

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        ...
    }
}

And real command that needs send to Slack

class ProcessImagesCommand extends NotifiesSlackCommand {
    public function handle() {/* do magic */}
}
Kyslik
  • 8,217
  • 5
  • 54
  • 87
  • Whoa, calm down. Thanks for your answer. It made me realise my question was ill formed. I'm not using the trait directly in the class which has the execute method. I'm using it in a class which extends the Command class. Thus: An inherited member from a base class is overridden by a member inserted by a Trait. http://php.net/manual/en/language.oop5.traits.php The main problem is capturing the console output. (i've tried something with ob_start()) – Martijn Imhoff Nov 07 '18 at 08:24