BaseConsumerCommand::getConsumer()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 2
b 0
f 0
1
<?php
2
namespace NeedleProject\LaravelRabbitMq\Command;
3
4
use Illuminate\Console\Command;
5
use Monolog\Handler\StreamHandler;
6
use Monolog\Logger;
7
use NeedleProject\LaravelRabbitMq\ConsumerInterface;
8
use Psr\Log\LoggerAwareInterface;
9
use Psr\Log\LoggerInterface;
10
use Symfony\Component\Console\Output\OutputInterface;
11
12
/**
13
 * Class BaseConsumerCommand
14
 *
15
 * @package NeedleProject\LaravelRabbitMq\Command
16
 * @author  Adrian Tilita <[email protected]>
17
 */
18
class BaseConsumerCommand extends Command
19
{
20
    /**
21
     * The name and signature of the console command.
22
     *
23
     * @var string
24
     */
25
    protected $signature = 'rabbitmq:consume {consumer} {--time=60} {--messages=100} {--memory=64}';
26
27
    /**
28
     * The console command description.
29
     *
30
     * @var string
31
     */
32
    protected $description = 'Start consuming messages';
33
34
    /**
35
     * @param string $consumerAliasName
36
     * @return ConsumerInterface
37
     */
38
    protected function getConsumer(string $consumerAliasName): ConsumerInterface
39
    {
40
        return app()->make(ConsumerInterface::class, [$consumerAliasName]);
41
    }
42
43
    /**
44
     * Execute the console command.
45
     * @return int
46
     */
47 2
    public function handle()
48
    {
49 2
        $messageCount = $this->input->getOption('messages');
50 2
        $waitTime = $this->input->getOption('time');
51 2
        $memoryLimit = $this->input->getOption('memory');
52 2
        $isVerbose = in_array(
53 2
            $this->output->getVerbosity(),
54 2
            [OutputInterface::VERBOSITY_VERBOSE, OutputInterface::VERBOSITY_VERY_VERBOSE]
55
        );
56
57
        /** @var ConsumerInterface $consumer */
58 2
        $consumer = $this->getConsumer($this->input->getArgument('consumer'));
59 2
        if ($consumer instanceof LoggerAwareInterface && $isVerbose) {
60
            try {
61
                $this->injectCliLogger($consumer);
62
            } catch (\Throwable $e) {
63
                // Do nothing, we cannot inject a STDOUT logger
64
            }
65
        }
66
        try {
67 2
            return $consumer->startConsuming($messageCount, $waitTime, $memoryLimit);
68 1
        } catch (\Throwable $e) {
69 1
            $consumer->stopConsuming();
70 1
            $this->output->error($e->getMessage());
71 1
            return -1;
72
        }
73
    }
74
75
    /**
76
     * Inject a stdout logger
77
     *
78
     * This is a "hackish" method because we handle a interface to deduce an implementation
79
     * that exposes certain methods.
80
     *
81
     * @todo - Find a better way to inject a CLI logger when running in verbose mode
82
     *
83
     * @param LoggerAwareInterface $consumerWithLogger
84
     * @throws \Exception
85
     */
86
    protected function injectCliLogger(LoggerAwareInterface $consumerWithLogger)
87
    {
88
        $stdHandler = new StreamHandler('php://stdout');
89
        $class = new \ReflectionClass(get_class($consumerWithLogger));
90
        $property = $class->getProperty('logger');
91
        $property->setAccessible(true);
92
        /** @var LoggerInterface $logger */
93
        $logger = $property->getValue($consumerWithLogger);
94
        if ($logger instanceof \Illuminate\Log\LogManager) {
95
            /** @var Logger $logger */
96
            $logger = $logger->channel()->getLogger();
0 ignored issues
show
Bug introduced by
The method channel() does not exist on Monolog\Logger. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

96
            $logger = $logger->/** @scrutinizer ignore-call */ channel()->getLogger();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
97
            $logger->pushHandler($stdHandler);
98
        }
99
        $property->setAccessible(false);
100
    }
101
}
102