]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - lib/nickname.php
Merge branch '0.9.x' into merge
[quix0rs-gnu-social.git] / lib / nickname.php
1 <?php
2 /*
3  * StatusNet - the distributed open-source microblogging tool
4  * Copyright (C) 2008, 2009, StatusNet, Inc.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 class Nickname
21 {
22     /**
23      * Regex fragment for pulling an arbitrarily-formated nickname.
24      *
25      * Not guaranteed to be valid after normalization; run the string through
26      * Nickname::normalize() to get the canonical form, or Nickname::isValid()
27      * if you just need to check if it's properly formatted.
28      *
29      * This and CANONICAL_FMT replace the old NICKNAME_FMT, but be aware
30      * that these should not be enclosed in []s.
31      */
32     const DISPLAY_FMT = '[0-9a-zA-Z_]+';
33
34     /**
35      * Regex fragment for checking a canonical nickname.
36      *
37      * Any non-matching string is not a valid canonical/normalized nickname.
38      * Matching strings are valid and canonical form, but may still be
39      * unavailable for registration due to blacklisting et.
40      *
41      * Only the canonical forms should be stored as keys in the database;
42      * there are multiple possible denormalized forms for each valid
43      * canonical-form name.
44      *
45      * This and DISPLAY_FMT replace the old NICKNAME_FMT, but be aware
46      * that these should not be enclosed in []s.
47      */
48     const CANONICAL_FMT = '[0-9a-z]{1,64}';
49
50     /**
51      * Maximum number of characters in a canonical-form nickname.
52      */
53     const MAX_LEN = 64;
54
55     /**
56      * Nice simple check of whether the given string is a valid input nickname,
57      * which can be normalized into an internally canonical form.
58      *
59      * Note that valid nicknames may be in use or reserved.
60      *
61      * @param string $str
62      * @return boolean
63      */
64     public static function isValid($str)
65     {
66         try {
67             self::normalize($str);
68             return true;
69         } catch (NicknameException $e) {
70             return false;
71         }
72     }
73
74     /**
75      * Validate an input nickname string, and normalize it to its canonical form.
76      * The canonical form will be returned, or an exception thrown if invalid.
77      *
78      * @param string $str
79      * @return string Normalized canonical form of $str
80      *
81      * @throws NicknameException (base class)
82      * @throws   NicknameInvalidException
83      * @throws   NicknameEmptyException
84      * @throws   NicknameTooLongException
85      */
86     public static function normalize($str)
87     {
88         $str = trim($str);
89         $str = str_replace('_', '', $str);
90         $str = mb_strtolower($str);
91
92         $len = mb_strlen($str);
93         if ($len < 1) {
94             throw new NicknameEmptyException();
95         } else if ($len > self::MAX_LEN) {
96             throw new NicknameTooLongException();
97         }
98         if (!self::isCanonical($str)) {
99             throw new NicknameInvalidException();
100         }
101
102         return $str;
103     }
104
105     /**
106      * Is the given string a valid canonical nickname form?
107      *
108      * @param string $str
109      * @return boolean
110      */
111     public static function isCanonical($str)
112     {
113         return preg_match('/^(?:' . self::CANONICAL_FMT . ')$/', $str);
114     }
115 }
116
117 class NicknameException extends ClientException
118 {
119     function __construct($msg=null, $code=400)
120     {
121         if ($msg === null) {
122             $msg = $this->defaultMessage();
123         }
124         parent::__construct($msg, $code);
125     }
126
127     /**
128      * Default localized message for this type of exception.
129      * @return string
130      */
131     protected function defaultMessage()
132     {
133         return null;
134     }
135 }
136
137 class NicknameInvalidException extends NicknameException {
138     /**
139      * Default localized message for this type of exception.
140      * @return string
141      */
142     protected function defaultMessage()
143     {
144         // TRANS: Validation error in form for registration, profile and group settings, etc.
145         return _('Nickname must have only lowercase letters and numbers and no spaces.');
146     }
147 }
148
149 class NicknameEmptyException extends NicknameException
150 {
151     /**
152      * Default localized message for this type of exception.
153      * @return string
154      */
155     protected function defaultMessage()
156     {
157         // TRANS: Validation error in form for registration, profile and group settings, etc.
158         return _('Nickname cannot be empty.');
159     }
160 }
161
162 class NicknameTooLongException extends NicknameInvalidException
163 {
164     /**
165      * Default localized message for this type of exception.
166      * @return string
167      */
168     protected function defaultMessage()
169     {
170         // TRANS: Validation error in form for registration, profile and group settings, etc.
171         return sprintf(_m('Nickname cannot be more than %d character long.',
172                           'Nickname cannot be more than %d characters long.',
173                           Nickname::MAX_LEN),
174                        Nickname::MAX_LEN);
175     }
176 }