BaseConsumerCommand   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
eloc 29
dl 0
loc 77
rs 10
c 3
b 1
f 0
wmc 8

3 Methods

Rating   Name   Duplication   Size   Complexity  
A handle() 0 24 5
A injectCliLogger() 0 14 2
A getConsumer() 0 3 1
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
    public function handle()
44
    {
45
        $messageCount = $this->input->getOption('messages');
46
        $waitTime = $this->input->getOption('time');
47
        $memoryLimit = $this->input->getOption('memory');
48
        $isVerbose = in_array(
49
            $this->output->getVerbosity(),
50
            [OutputInterface::VERBOSITY_VERBOSE, OutputInterface::VERBOSITY_VERY_VERBOSE]
51
        );
52
53
        /** @var ConsumerInterface $consumer */
54
        $consumer = $this->getConsumer($this->input->getArgument('consumer'));
55
        if ($consumer instanceof LoggerAwareInterface && $isVerbose) {
56
            try {
57
                $this->injectCliLogger($consumer);
58
            } catch (\Throwable $e) {
59
                // Do nothing, we cannot inject a STDOUT logger
60
            }
61
        }
62
        try {
63
            return $consumer->startConsuming($messageCount, $waitTime, $memoryLimit);
64
        } catch (\Throwable $e) {
65
            $consumer->stopConsuming();
66
            throw $e;
67
        }
68
    }
69
70
    /**
71
     * Inject a stdout logger
72
     *
73
     * This is a "hackish" method because we handle a interface to deduce an implementation
74
     * that exposes certain methods.
75
     *
76
     * @todo - Find a better way to inject a CLI logger when running in verbose mode
77
     *
78
     * @param LoggerAwareInterface $consumerWithLogger
79
     * @throws \Exception
80
     */
81
    protected function injectCliLogger(LoggerAwareInterface $consumerWithLogger)
82
    {
83
        $stdHandler = new StreamHandler('php://stdout');
84
        $class = new \ReflectionClass(get_class($consumerWithLogger));
85
        $property = $class->getProperty('logger');
86
        $property->setAccessible(true);
87
        /** @var LoggerInterface $logger */
88
        $logger = $property->getValue($consumerWithLogger);
89
        if ($logger instanceof \Illuminate\Log\LogManager) {
90
            /** @var Logger $logger */
91
            $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

91
            $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...
92
            $logger->pushHandler($stdHandler);
93
        }
94
        $property->setAccessible(false);
95
    }
96
}
97