Passed
Push — master ( 831177...1585b1 )
by Jeroen
01:32
created

IrcClient::sendMessage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Jerodev\PhpIrcClient;
4
5
use Exception;
6
use Jerodev\PhpIrcClient\Helpers\EventHandlerCollection;
7
use Jerodev\PhpIrcClient\Messages\IrcMessage;
8
9
class IrcClient
10
{
11
    /** @var IrcChannel[] */
12
    private $channels;
13
    
14
    /** @var IrcConnection */
15
    private $connection;
16
17
    /** @var bool */
18
    private $isAuthenticated;
19
20
    /** @var EventHandlerCollection */
21
    private $messageEventHandlers;
22
23
    /** @var IrcUser|null */
24
    private $user;
25
26
    /**
27
     *  Create a new IrcClient instance.
28
     *
29
     *  @param string $server The server address to connect to including the port: `address:port`.
30
     *  @param null|string $username The username to use on the server. Can be set in more detail using `setUser()`.
31
     *  @param null|string|string[] $channels The channels to join on connect.
32
     */
33
    public function __construct(string $server, $username = null, $channels = null)
34
    {
35
        $this->connection = new IrcConnection($server);
36
        
37
        $this->user = $username === null ? null : new IrcUser($username);
38
        $this->channels = [];
39
        $this->messageEventHandlers = new EventHandlerCollection();
40
41
        if (!empty($channels)) {
42
            if (is_string($channels)) {
43
                $channels = [$channels];
44
            }
45
46
            foreach ($channels as $channel) {
47
                $this->channels[$channel] = new IrcChannel($channel);
48
            }
49
        }
50
    }
51
52
    /**
53
     *  Set the user credentials for the connections.
54
     *  When a connection is already open, this function can be used to change the nickname of the client.
55
     *
56
     *  @param IrcUser|string $user The user information.
57
     */
58
    public function setUser($user): void
59
    {
60
        if (is_string($user)) {
61
            $user = new IrcUser($user);
62
        }
63
64
        if ($this->connection->isConnected() && $this->user->nickname !== $user->nickname) {
65
            $this->sendCommand("NICK :$user->nickname");
66
        }
67
68
        $this->user = $user;
69
    }
70
71
    /**
72
     *  Connect to the irc server and start listening for messages.
73
     *
74
     *  @throws Exception if no user information is provided before connecting.
75
     */
76
    public function connect(): void
77
    {
78
        if (!$this->user) {
79
            throw new Exception('A nickname must be set before connecting to an irc server.');
80
        }
81
82
        if ($this->connection->isConnected()) {
83
            return;
84
        }
85
86
        $this->isAuthenticated = false;
87
        $this->connection->onData(function ($msg) {
88
            $this->handleIrcMessage($msg);
89
        });
90
        $this->connection->open();
91
    }
92
93
    /**
94
     *  Close the current connection, if any.
95
     */
96
    public function disconnect(): void
97
    {
98
        $this->connection->close();
99
    }
100
101
    /**
102
     *  Send a raw command string to the irc server.
103
     *
104
     *  @param string $command The full command string to send.
105
     */
106
    public function sendCommand(string $command): void
107
    {
108
        $this->connection->write($command);
109
    }
110
111
    /**
112
     *  Send a message to a channel or user.
113
     *  To send to a channel, make sure the `$target` starts with a `#`.
114
     *
115
     *  @param string $target The channel or user to message.
116
     *  @param string $message The message to send.
117
     */
118
    public function sendMessage(string $target, string $message): void
119
    {
120
        $this->sendCommand("PRIVMSG $target :$message");
121
    }
122
    
123
    /**
124
     *  Grab channel information by its name.
125
     *  This function makes sure the channel exists on this client first.
126
     *
127
     *  @param string $name The name of this channel.
128
     *
129
     *  @return IrcChannel
130
     */
131
    public function getChannel(string $name): IrcChannel
132
    {
133
        if (($this->channels[$name] ?? null) === null) {
134
            $this->channels[$name] = new IrcChannel($name);
135
        }
136
137
        return $this->channels[$name];
138
    }
139
    
140
    /**
141
     *  Return a list of all channels
142
     *
143
     *  @return IrcChannel[]
144
     */
145
    public function getChannels(): array
146
    {
147
        return $this->channels;
148
    }
149
150
    /**
151
     *  Take actions required for received irc messages and invoke the correct event handlers.
152
     *
153
     *  @param IrcMessage $message The message object for the received line.
154
     */
155
    private function handleIrcMessage(IrcMessage $message): void
156
    {
157
        $message->handle($this);
158
159
        if (!$this->isAuthenticated && $this->user) {
160
            $this->sendCommand("USER {$this->user->nickname} * * :{$this->user->nickname}");
161
            $this->sendCommand("NICK {$this->user->nickname}");
162
            $this->isAuthenticated = true;
163
        }
164
        
165
        //$this->messageEventHandlers->invoke($message->command, [$message]);
166
    }
167
}
168