mode handler
[PHP-P10.git] / Uplink / P10_ModeSets.class.php
1 <?php
2 /********************************* PHP-P10 ******************************
3  *    P10 uplink class by pk910   (c)2011 pk910                         *
4  ************************************************************************
5  *                          Version 2 (OOP)                             *
6  *                                                                      *
7  * PHP-P10 is free software; you can redistribute it and/or modify      *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or    *
10  * (at your option) any later version.                                  *
11  *                                                                      *
12  * This program is distributed in the hope that it will be useful,      *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
15  * GNU General Public License for more details.                         *
16  *                                                                      *
17  * You should have received a copy of the GNU General Public License    *
18  * along with PHP-P10; if not, write to the Free Software Foundation,   *
19  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.       *
20  *                                                                      *
21  ************************************************************************
22  * 
23  *  Uplink/P10_ModeSets.class.php
24  *
25  * classes to parse and store channel or user modes
26  *
27  */
28
29 class P10_ChannelModeSet {
30         const MODE_TYPE_A = 1, MODE_TYPE_B = 2, MODE_TYPE_C = 3, MODE_TYPE_D = 4;
31         /** http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt
32          * Section 3.3 CHANMODES
33          *
34          * Type A: Modes that add or remove an address to or from a list.
35          *   These modes always take a parameter when sent by the server to a
36          *   client; when sent by a client, they may be specified without a
37          *   parameter, which requests the server to display the current
38          *   contents of the corresponding list on the channel to the client.
39          *
40          * Type B: Modes that change a setting on the channel.  These modes
41          *   always take a parameter.
42          *
43          * Type C: Modes that change a setting on the channel. These modes
44          *   take a parameter only when set; the parameter is absent when the
45          *   mode is removed both in the client's and server's MODE command.
46          *
47          * Type D: Modes that change a setting on the channel. These modes
48          *   never take a parameter.
49          **/
50         private static $modes = array(
51                 "b" => self::MODE_TYPE_A,
52                 "k" => self::MODE_TYPE_B,
53                 "a" => self::MODE_TYPE_C,
54                 "l" => self::MODE_TYPE_C,
55                 "f" => self::MODE_TYPE_C,
56                 "F" => self::MODE_TYPE_C,
57                 "c" => self::MODE_TYPE_D,
58                 "C" => self::MODE_TYPE_D,
59                 "i" => self::MODE_TYPE_D,
60                 "m" => self::MODE_TYPE_D,
61                 "M" => self::MODE_TYPE_D,
62                 "n" => self::MODE_TYPE_D,
63                 "N" => self::MODE_TYPE_D,
64                 "p" => self::MODE_TYPE_D,
65                 "r" => self::MODE_TYPE_D,
66                 "s" => self::MODE_TYPE_D,
67                 "t" => self::MODE_TYPE_D,
68                 "u" => self::MODE_TYPE_D,
69                 "D" => self::MODE_TYPE_D,
70                 "d" => self::MODE_TYPE_D,
71                 "R" => self::MODE_TYPE_D,
72                 "z" => self::MODE_TYPE_D
73         );
74         private static $modevalues = null;
75         private $modeflags = 0;
76         private $modeparams = array();
77         
78         public __construct($modes) {
79                 if(self::$modevalues == null) {
80                         //build modevalues array
81                         $flag = 1;
82                         self::$modevalues = array();
83                         foreach(self::$modes as $mode => $type) {
84                                 self::$modevalues[$mode] = $flag;
85                                 $flag <<= 1;
86                         }
87                 }
88                 $this->parseModes($modes);
89         }
90         
91         public parseModes($modes) {
92                 $args = explode(" ",$modes);
93                 $c = 1;
94                 for($i = 0; $i < strlen($args[0]); $i++) {
95                         $mode = $args[0][$i];
96                         if($mode == "+") continue;
97                         if($mode == "-") { //we have no - flag on parseModes???
98                                 trigger_error("unexpected MODE_DEL (-) on parseModes (".$modes.").", E_USER_WARNING);
99                                 break;
100                         }
101                         if(!array_key_exists($mode, self::$modevalues)) {
102                                 trigger_error("unknown mode (".$mode.") on parseModes (".$modes.").", E_USER_WARNING);
103                                 continue;
104                         }
105                         $flag = self::$modevalues[$mode];
106                         if(self::$modevalues[$mode] == self::MODE_TYPE_A) continue; //we shouldn't get such a mode on parseModes
107                         $this->modeflags |= $flag;
108                         if(self::$modevalues[$mode] == self::MODE_TYPE_B || self::$modevalues[$mode] == self::MODE_TYPE_C) {
109                                 $this->modeparams[$mode] = $args[$c++];
110                         }
111                 }
112         }
113         
114         public setModes($modes, $returndiff = false) {
115                 $args = explode(" ",$modes);
116                 $c = 1;
117                 $add = true;
118                 $modestradd = "+";
119                 $paramstradd = "";
120                 $modestrdel = "-";
121                 $paramstrdel = "";
122                 for($i = 0; $i < strlen($args[0]); $i++) {
123                         $mode = $args[0][$i];
124                         if($mode == "+") {
125                                 $add = true;
126                                 continue;
127                         }
128                         if($mode == "-") { 
129                                 $add = false;
130                                 continue;
131                         }
132                         if(!array_key_exists($mode, self::$modevalues)) {
133                                 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
134                                 continue;
135                         }
136                         $flag = self::$modevalues[$mode];
137                         if($add) {
138                                 if($returndiff && !($this->modeflags & $flag)) {
139                                         $modestradd .= $mode;
140                                         if(self::$modevalues[$mode] == self::MODE_TYPE_B || self::$modevalues[$mode] == self::MODE_TYPE_C) {
141                                                 $paramstradd .= " ".$args[$c];
142                                         }
143                                 }
144                                 $this->modeflags |= $flag;
145                                 if(self::$modevalues[$mode] == self::MODE_TYPE_B || self::$modevalues[$mode] == self::MODE_TYPE_C) {
146                                         $this->modeparams[$mode] = $args[$c++];
147                                 }
148                         } else {
149                                 if($returndiff && ($this->modeflags & $flag)) {
150                                         $modestrdel .= $mode;
151                                         if(self::$modevalues[$mode] == self::MODE_TYPE_C) {
152                                                 $paramstrdel .= " ".$args[$c];
153                                         }
154                                 }
155                                 $this->modeflags &= ~$flag;
156                                 if(self::$modevalues[$mode] == self::MODE_TYPE_B || self::$modevalues[$mode] == self::MODE_TYPE_C) {
157                                         unset($this->modeparams[$mode]);
158                                 }
159                                 if(self::$modevalues[$mode] == self::MODE_TYPE_C) $c++;
160                         }
161                 }
162                 if($returndiff) {
163                         $modediff = ($modestradd == "+" ? "" : $modestradd);
164                         $modediff .= ($modestrdel == "-" ? "" : $modestrdel);
165                         $modediff .= $paramstradd.$paramstrdel;
166                         return $modediff;
167                 }
168         }
169         
170         public getModeString() {
171                 $modestr = "+";
172                 $paramstr = "";
173                 foreach(self::$modevalues as $mode => $flag) {
174                         if(($this->modeflags & $flag)) {
175                                 $modestr .= $mode;
176                                 if(self::$modevalues[$mode] == self::MODE_WITH_PARAMETER) {
177                                         $paramstr .= " ".$this->modeparams[$mode];
178                                 }
179                         }
180                 }
181                 return $modestr.$paramstr;
182         }
183         
184 }
185
186 class P10_UserModeSet {
187         const MODE_WITHOUT_PARAMETER = 1, MODE_WITH_PARAMETER = 2;
188         private static $modes = array(
189                 "o" => self::MODE_WITHOUT_PARAMETER,
190                 "O" => self::MODE_WITHOUT_PARAMETER,
191                 "i" => self::MODE_WITHOUT_PARAMETER,
192                 "w" => self::MODE_WITHOUT_PARAMETER,
193                 "s" => self::MODE_WITHOUT_PARAMETER,
194                 "d" => self::MODE_WITHOUT_PARAMETER,
195                 "k" => self::MODE_WITHOUT_PARAMETER,
196                 "g" => self::MODE_WITH_PARAMETER,
197                 "r" => self::MODE_WITH_PARAMETER,
198                 "f" => self::MODE_WITH_PARAMETER,
199                 "n" => self::MODE_WITHOUT_PARAMETER,
200                 "I" => self::MODE_WITHOUT_PARAMETER,
201                 "X" => self::MODE_WITHOUT_PARAMETER,
202                 "S" => self::MODE_WITHOUT_PARAMETER,
203                 "H" => self::MODE_WITHOUT_PARAMETER,
204                 "c" => self::MODE_WITHOUT_PARAMETER,
205                 "W" => self::MODE_WITHOUT_PARAMETER,
206                 "t" => self::MODE_WITHOUT_PARAMETER,
207                 "D" => self::MODE_WITHOUT_PARAMETER,
208                 "x" => self::MODE_WITHOUT_PARAMETER
209         );
210         private static $modevalues = null;
211         private $modeflags = 0;
212         private $modeparams = array();
213         
214         public __construct($modes) {
215                 if(self::$modevalues == null) {
216                         //build modevalues array
217                         $flag = 1;
218                         self::$modevalues = array();
219                         foreach(self::$modes as $mode => $type) {
220                                 self::$modevalues[$mode] = $flag;
221                                 $flag <<= 1;
222                         }
223                 }
224                 $this->parseModes($modes);
225         }
226         
227         public parseModes($modes) {
228                 $args = explode(" ",$modes);
229                 $c = 1;
230                 for($i = 0; $i < strlen($args[0]); $i++) {
231                         $mode = $args[0][$i];
232                         if($mode == "+") continue;
233                         if($mode == "-") { //we have no - flag on parseModes???
234                                 trigger_error("unexpected MODE_DEL (-) on parseModes (".$modes.").", E_USER_WARNING);
235                                 break;
236                         }
237                         if(!array_key_exists($mode, self::$modevalues)) {
238                                 trigger_error("unknown mode (".$mode.") on parseModes (".$modes.").", E_USER_WARNING);
239                                 continue;
240                         }
241                         $flag = self::$modevalues[$mode];
242                         $this->modeflags |= $flag;
243                         if(self::$modevalues[$mode] == self::MODE_WITH_PARAMETER) {
244                                 $this->modeparams[$mode] = $args[$c++];
245                         }
246                 }
247         }
248         
249         public setModes($modes, $returndiff = false) {
250                 $args = explode(" ",$modes);
251                 $c = 1;
252                 $add = true;
253                 $modestradd = "+";
254                 $paramstradd = "";
255                 $modestrdel = "-";
256                 for($i = 0; $i < strlen($args[0]); $i++) {
257                         $mode = $args[0][$i];
258                         if($mode == "+") {
259                                 $add = true;
260                                 continue;
261                         }
262                         if($mode == "-") { 
263                                 $add = false;
264                                 continue;
265                         }
266                         if(!array_key_exists($mode, self::$modevalues)) {
267                                 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
268                                 continue;
269                         }
270                         $flag = self::$modevalues[$mode];
271                         if($add) {
272                                 if($returndiff && !($this->modeflags & $flag)) {
273                                         $modestradd .= $mode;
274                                         if(self::$modevalues[$mode] == self::MODE_WITH_PARAMETER) {
275                                                 $paramstradd .= " ".$args[$c];
276                                         }
277                                 }
278                                 $this->modeflags |= $flag;
279                                 if(self::$modevalues[$mode] == self::MODE_WITH_PARAMETER) {
280                                         $this->modeparams[$mode] = $args[$c++];
281                                 }
282                         } else {
283                                 if($returndiff && ($this->modeflags & $flag)) {
284                                         $modestrdel .= $mode;
285                                 }
286                                 $this->modeflags &= ~$flag;
287                         }
288                 }
289                 if($returndiff) {
290                         $modediff = ($modestradd == "+" ? "" : $modestradd);
291                         $modediff .= ($modestrdel == "-" ? "" : $modestrdel);
292                         $modediff .= $paramstradd;
293                         return $modediff;
294                 }
295         }
296         
297         public getModeString() {
298                 $modestr = "+";
299                 $paramstr = "";
300                 foreach(self::$modevalues as $mode => $flag) {
301                         if(($this->modeflags & $flag)) {
302                                 $modestr .= $mode;
303                                 if(self::$modevalues[$mode] == self::MODE_WITH_PARAMETER) {
304                                         $paramstr .= " ".$this->modeparams[$mode];
305                                 }
306                         }
307                 }
308                 return $modestr.$paramstr;
309         }
310         
311 }
312
313 ?>