]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/Irc/extlib/phergie/Phergie/Plugin/UserInfo.php
Merge branch '0.9.x' into 1.0.x
[quix0rs-gnu-social.git] / plugins / Irc / extlib / phergie / Phergie / Plugin / UserInfo.php
1 <?php
2 /**
3  * Phergie
4  *
5  * PHP version 5
6  *
7  * LICENSE
8  *
9  * This source file is subject to the new BSD license that is bundled
10  * with this package in the file LICENSE.
11  * It is also available through the world-wide-web at this URL:
12  * http://phergie.org/license
13  *
14  * @category  Phergie
15  * @package   Phergie_Plugin_UserInfo
16  * @author    Phergie Development Team <team@phergie.org>
17  * @copyright 2008-2010 Phergie Development Team (http://phergie.org)
18  * @license   http://phergie.org/license New BSD License
19  * @link      http://pear.phergie.org/package/Phergie_Plugin_UserInfo
20  */
21
22 /**
23  * Provides an API for querying information on users.
24  *
25  * @category Phergie
26  * @package  Phergie_Plugin_UserInfo
27  * @author   Phergie Development Team <team@phergie.org>
28  * @license  http://phergie.org/license New BSD License
29  * @link     http://pear.phergie.org/package/Phergie_Plugin_UserInfo
30  */
31 class Phergie_Plugin_UserInfo extends Phergie_Plugin_Abstract
32 {
33     const REGULAR = 1;
34     const VOICE   = 2;
35     const HALFOP  = 4;
36     const OP      = 8;
37     const ADMIN   = 16;
38     const OWNER   = 32;
39
40     /**
41      * An array containing all the user information for a given channel
42      *
43      * @var array
44      */
45     protected $store = array();
46
47     /**
48      * Tracks mode changes
49      *
50      * @return void
51      */
52     public function onMode()
53     {
54         $args = $this->event->getArguments();
55
56         if (count($args) != 3) {
57             return;
58         }
59
60         list($chan, $modes, $nicks) = $args;
61
62         if (!preg_match('/(?:\+|-)[hovaq+-]+/i', $modes)) {
63             return;
64         }
65
66         $chan = trim(strtolower($chan));
67         $modes = str_split(trim(strtolower($modes)), 1);
68         $nicks = explode(' ', trim(strtolower($nicks)));
69         $operation = array_shift($modes); // + or -
70
71         while ($char = array_shift($modes)) {
72             $nick = array_shift($nicks);
73             $mode = null;
74
75             switch ($char) {
76             case 'q':
77                 $mode = self::OWNER;
78                 break;
79             case 'a':
80                 $mode = self::ADMIN;
81                 break;
82             case 'o':
83                 $mode = self::OP;
84                 break;
85             case 'h':
86                 $mode = self::HALFOP;
87                 break;
88             case 'v':
89                 $mode = self::VOICE;
90                 break;
91             }
92
93             if (!empty($mode)) {
94                 if ($operation == '+') {
95                     $this->store[$chan][$nick] |= $mode;
96                 } else if ($operation == '-') {
97                     $this->store[$chan][$nick] ^= $mode;
98                 }
99             }
100         }
101     }
102
103     /**
104      * Tracks users joining a channel
105      *
106      * @return void
107      */
108     public function onJoin()
109     {
110         $chan = trim(strtolower($this->event->getArgument(0)));
111         $nick = trim(strtolower($this->event->getNick()));
112
113         $this->store[$chan][$nick] = self::REGULAR;
114     }
115
116     /**
117      * Tracks users leaving a channel
118      *
119      * @return void
120      */
121     public function onPart()
122     {
123         $chan = trim(strtolower($this->event->getArgument(0)));
124         $nick = trim(strtolower($this->event->getNick()));
125
126         if (isset($this->store[$chan][$nick])) {
127             unset($this->store[$chan][$nick]);
128         }
129     }
130
131     /**
132      * Tracks users quitting a server
133      *
134      * @return void
135      */
136     public function onQuit()
137     {
138         $nick = trim(strtolower($this->event->getNick()));
139
140         foreach ($this->store as $chan => $store) {
141             if (isset($store[$nick])) {
142                 unset($this->store[$chan][$nick]);
143             }
144         }
145     }
146
147     /**
148      * Tracks users changing nicks
149      *
150      * @return void
151      */
152     public function onNick()
153     {
154         $nick = trim(strtolower($this->event->getNick()));
155         $newNick = trim(strtolower($this->event->getArgument(0)));
156
157         foreach ($this->store as $chan => $store) {
158             if (isset($store[$nick])) {
159                 $this->store[$chan][$newNick] = $store[$nick];
160                 unset($this->store[$chan][$nick]);
161             }
162         }
163     }
164
165     /**
166      * Populates the internal user listing for a channel when the bot joins it.
167      *
168      * @return void
169      */
170     public function onResponse()
171     {
172         if ($this->event->getCode() != Phergie_Event_Response::RPL_NAMREPLY) {
173             return;
174         }
175
176         $desc = preg_split('/[@*=]\s*/', $this->event->getDescription(), 2);
177         list($chan, $users) = array_pad(explode(' :', trim($desc[1])), 2, null);
178         $users = explode(' ', trim($users));
179
180         $chan = trim(strtolower($chan));
181
182         foreach ($users as $user) {
183             if (empty($user)) {
184                 continue;
185             }
186
187             $user = trim(strtolower($user));
188             $flag = self::REGULAR;
189
190             if ($user[0] == '~') {
191                 $flag |= self::OWNER;
192             } else if ($user[0] == '&') {
193                 $flag |= self::ADMIN;
194             } else if ($user[0] == '@') {
195                 $flag |= self::OP;
196             } else if ($user[0] == '%') {
197                 $flag |= self::HALFOP;
198             } else if ($user[0] == '+') {
199                 $flag |= self::VOICE;
200             }
201
202             if ($flag != self::REGULAR) {
203                 $user = substr($user, 1);
204             }
205
206             $this->store[$chan][$user] = $flag;
207         }
208     }
209
210     /**
211      * Debugging function
212      *
213      * @return void
214      */
215     public function onPrivmsg()
216     {
217         if ($this->getConfig('debug', false) == false) {
218             return;
219         }
220
221         list($target, $msg) = array_pad($this->event->getArguments(), 2, null);
222
223         if (preg_match('#^ishere (\S+)$#', $msg, $m)) {
224             $this->doPrivmsg($target, $this->isIn($m[1], $target) ? 'true' : 'false');
225         } elseif (preg_match('#^isowner (\S+)$#', $msg, $m)) {
226             $this->doPrivmsg($target, $this->isOwner($m[1], $target) ? 'true' : 'false');
227         } elseif (preg_match('#^isadmin (\S+)$#', $msg, $m)) {
228             $this->doPrivmsg($target, $this->isAdmin($m[1], $target) ? 'true' : 'false');
229         } elseif (preg_match('#^isop (\S+)$#', $msg, $m)) {
230             $this->doPrivmsg($target, $this->isOp($m[1], $target) ? 'true' : 'false');
231         } elseif (preg_match('#^ishop (\S+)$#', $msg, $m)) {
232             $this->doPrivmsg($target, $this->isHalfop($m[1], $target) ? 'true' : 'false');
233         } elseif (preg_match('#^isvoice (\S+)$#', $msg, $m)) {
234             $this->doPrivmsg($target, $this->isVoice($m[1], $target) ? 'true' : 'false');
235         } elseif (preg_match('#^channels (\S+)$#', $msg, $m)) {
236             $channels = $this->getChannels($m[1]);
237             $this->doPrivmsg($target, $channels ? join(', ', $channels) : 'unable to find nick');
238         } elseif (preg_match('#^users (\S+)$#', $msg, $m)) {
239             $nicks = $this->getUsers($m[1]);
240             $this->doPrivmsg($target, $nicks ? join(', ', $nicks) : 'unable to find channel');
241         } elseif (preg_match('#^random (\S+)$#', $msg, $m)) {
242             $nick = $this->getrandomuser($m[1]);
243             $this->doPrivmsg($target, $nick ? $nick : 'unable to  find channel');
244         }
245     }
246
247     /**
248      * Checks whether or not a given user has a mode
249      *
250      * @param int    $mode A numeric mode (identified by the class constants)
251      * @param string $nick The nick to check
252      * @param string $chan The channel to check in
253      *
254      * @return bool
255      */
256     public function is($mode, $nick, $chan)
257     {
258         $chan = trim(strtolower($chan));
259         $nick = trim(strtolower($nick));
260
261         if (!isset($this->store[$chan][$nick])) {
262             return false;
263         }
264
265         return ($this->store[$chan][$nick] & $mode) != 0;
266     }
267
268     /**
269      * Checks whether or not a given user has owner (~) status
270      *
271      * @param string $nick The nick to check
272      * @param string $chan The channel to check in
273      *
274      * @return bool
275      */
276     public function isOwner($nick, $chan)
277     {
278         return $this->is(self::OWNER, $nick, $chan);
279     }
280
281     /**
282      * Checks whether or not a given user has admin (&) status
283      *
284      * @param string $nick The nick to check
285      * @param string $chan The channel to check in
286      *
287      * @return bool
288      */
289     public function isAdmin($nick, $chan)
290     {
291         return $this->is(self::ADMIN, $nick, $chan);
292     }
293
294     /**
295      * Checks whether or not a given user has operator (@) status
296      *
297      * @param string $nick The nick to check
298      * @param string $chan The channel to check in
299      *
300      * @return bool
301      */
302     public function isOp($nick, $chan)
303     {
304         return $this->is(self::OP, $nick, $chan);
305     }
306
307     /**
308      * Checks whether or not a given user has halfop (%) status
309      *
310      * @param string $nick The nick to check
311      * @param string $chan The channel to check in
312      *
313      * @return bool
314      */
315     public function isHalfop($nick, $chan)
316     {
317         return $this->is(self::HALFOP, $nick, $chan);
318     }
319
320     /**
321      * Checks whether or not a given user has voice (+) status
322      *
323      * @param string $nick The nick to check
324      * @param string $chan The channel to check in
325      *
326      * @return bool
327      */
328     public function isVoice($nick, $chan)
329     {
330         return $this->is(self::VOICE, $nick, $chan);
331     }
332
333     /**
334      * Checks whether or not a given user is in a channel
335      *
336      * @param string $nick The nick to check
337      * @param string $chan The channel to check in
338      *
339      * @return bool
340      */
341     public function isIn($nick, $chan)
342     {
343         return $this->is(self::REGULAR, $nick, $chan);
344     }
345
346     /**
347      * Returns the entire user list for a channel or false if the bot is not
348      * in the channel.
349      *
350      * @param string $chan The channel name
351      *
352      * @return array|bool
353      */
354     public function getUsers($chan)
355     {
356         $chan = trim(strtolower($chan));
357         if (isset($this->store[$chan])) {
358             return array_keys($this->store[$chan]);
359         }
360         return false;
361     }
362
363     /**
364      * Returns the nick of a random user present in a given channel or false
365      * if the bot is not present in the channel.
366      *
367      * @param string $chan The channel name
368      *
369      * @return array|bool
370      */
371     public function getRandomUser($chan)
372     {
373         $chan = trim(strtolower($chan));
374
375         if (isset($this->store[$chan])) {
376             $ignore = array('chanserv', 'q', 'l', 's');
377
378             do {
379                 $nick = array_rand($this->store[$chan], 1);
380             } while (in_array($nick, $ignore));
381
382             return $nick;
383         }
384
385         return false;
386     }
387
388     /**
389      * Returns a list of channels in which a given user is present.
390      *
391      * @param string $nick Nick of the user (optional, defaults to the bot's
392      *               nick)
393      *
394      * @return array|bool
395      */
396     public function getChannels($nick = null)
397     {
398         if (empty($nick)) {
399             $nick = $this->connection->getNick();
400         }
401
402         $nick = trim(strtolower($nick));
403         $channels = array();
404
405         foreach ($this->store as $chan => $store) {
406             if (isset($store[$nick])) {
407                 $channels[] = $chan;
408             }
409         }
410
411         return $channels;
412     }
413 }