Completed
Push — develop ( 2f90e1...bffb25 )
by Kirill
07:59
created

GitterRoomListenCommand::onMessage()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
c 5
b 0
f 0
dl 0
loc 12
rs 9.4285
cc 2
eloc 6
nc 2
nop 1
1
<?php
2
/**
3
 * This file is part of GitterBot package.
4
 *
5
 * @author Serafim <[email protected]>
6
 * @date 26.01.2016 4:57
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
namespace App\Console\Commands;
12
13
14
use App\Gitter\Extensions\Middlewares\MessageBus;
15
use App\Support\Lazy\EloquentReader;
16
use App\User;
17
use App\Room;
18
use App\Message;
19
use Carbon\Carbon;
20
use App\Gitter\Client;
21
use React\EventLoop\LoopInterface;
22
use Gitter\Models\Room as GitterRoom;
23
use Gitter\Models\User as GitterUser;
24
use Illuminate\Contracts\Config\Repository;
25
use Gitter\Models\Message as GitterMessage;
26
use App\Gitter\Extensions\MiddlewareBuilder;
27
use Illuminate\Contracts\Container\Container;
28
use Gitter\Iterators\PromiseIterator\Controls;
29
30
31
/**
32
 * Class GitterRoomListenCommand
33
 * @package App\Console\Commands
34
 *
35
 * Прослушивание сообщений требуемой комнаты
36
 */
37
class GitterRoomListenCommand extends AbstractCommand
38
{
39
    /**
40
     * @var string
41
     */
42
    protected $signature = 'gitter:listen {room}';
43
44
    /**
45
     * @var string
46
     */
47
    protected $description = 'Listen gitter room';
48
49
    /**
50
     * Execute the console command.
51
     *
52
     * @param Repository $config
53
     * @param Container $container
54
     *
55
     * @return mixed
56
     */
57
    public function handle(Repository $config, Container $container)
58
    {
59
        /** @var Client $client */
60
        $client = $this->createClient($container, $config->get('gitter.token'));
61
62
63
        $this->auth($client, function (User $user) use ($client) {
0 ignored issues
show
Unused Code introduced by
The parameter $user is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
64
            $this->findRoom($client, $this->argument('room'), function (GitterRoom $room) use ($client) {
0 ignored issues
show
Bug introduced by
It seems like $this->argument('room') targeting Illuminate\Console\Command::argument() can also be of type array; however, App\Console\Commands\AbstractCommand::findRoom() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
65
                $this->listen($room, true);
66
            });
67
        });
68
69
70
        /** @var LoopInterface $loop */
71
        $loop = $container->make(LoopInterface::class);
72
        $loop->run();
73
    }
74
75
    /**
76
     * @param Client $client
77
     * @param \Closure $callback
78
     */
79
    protected function auth(Client $client, \Closure $callback)
80
    {
81
        GitterUser::current($client)
82
            ->then(function (GitterUser $gitterUser) use ($callback) {
83
                $user = User::make($gitterUser);
84
                \Auth::setUser($user);
85
86
                $callback($user);
87
            });
88
    }
89
90
    /**
91
     * @param GitterRoom $gitter
92
     * @param bool $startup
93
     * @return $this
94
     */
95
    protected function listen(GitterRoom $gitter, $startup = false)
96
    {
97
        /** @var Room $room */
98
        $room = Room::make($gitter, function (Room $room) {
99
            $this->call('gitter:sync', [
100
                'room'       => $room->gitter_id,
101
                '--users'    => true,
102
                '--messages' => true,
103
            ]);
104
        });
105
106
        /** @var LoopInterface $loop */
107
        $loop = app(LoopInterface::class);
108
109
        if ($startup) {
110
            //MessageBus::disableAll();
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
111
            $this->info('Fetching last messages...');
112
            $this->onMessageFallback($loop, $gitter, 1);
113
114
            return $this;
115
        }
116
117
        MessageBus::enableAll();
118
        $this->info(sprintf(
119
            'Startup gitter listener for %s at [%s]',
120
            $room->url,
121
            Carbon::now()->toDateTimeString()
122
        ));
123
124
        $gitter->onMessage(function (GitterMessage $msg) {
125
            app(Client::class)->setFallbackMode(false);
126
            $this->onMessage($msg);
127
128
        }, function (\Throwable $e) use ($loop, $gitter) {
0 ignored issues
show
Unused Code introduced by
The parameter $e is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
129
            $this->warn('Stream not available. Use message fallback fetch mode.');
130
131
            app(Client::class)->setFallbackMode(true);
132
            $this->onMessageFallback($loop, $gitter);
133
        });
134
135
        return $this;
136
    }
137
138
    /**
139
     * @param LoopInterface $loop
140
     * @param GitterRoom $gitter
141
     * @param int $timeout
142
     */
143
    protected function onMessageFallback(LoopInterface $loop, GitterRoom $gitter, $timeout = 10)
144
    {
145
        /** @var Message $lastMessage */
146
        $lastMessage = Message::where('room_id', $gitter->id)
147
            ->latest('created_at')
148
            ->first();
149
150
        if ($lastMessage) {
151 View Code Duplication
            $loop->addTimer($timeout, function () use ($gitter, $lastMessage) {
0 ignored issues
show
Documentation introduced by
$timeout is of type integer, but the function expects a object<React\EventLoop\numeric>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
152
                $gitter
153
                    ->getMessages($lastMessage->gitter_id, GitterRoom::MESSAGE_FETCH_ASC)
154
                    ->fetch(function (GitterMessage $message, Controls $controls) {
155
                        $this->onMessage($message);
156
                        $controls->next();
157
                    })
158
                    ->then(function () use ($gitter) {
159
                        $this->warn('Connection...');
160
                        $this->listen($gitter);
161
                    });
162
            });
163
        } else {
164
            $this->listen($gitter);
165
        }
166
    }
167
168
    /**
169
     * @param GitterMessage $gitter
170
     */
171
    protected function onMessage(GitterMessage $gitter)
172
    {
173
        $message = Message::make($gitter);
174
175
        if ($message->gitter_id === \Auth::user()->gitter_id) {
176
            return;
177
        }
178
179
        /** @var MiddlewareBuilder $builder */
180
        $builder = app(MiddlewareBuilder::class);
181
        $builder->fire($gitter->room, $message);
182
    }
183
}
184
185
186
187
188
189