Merge branch '2.0'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / util / UserUtil.class.php
CommitLineData
158bd3ca
TD
1<?php
2namespace wcf\util;
3use wcf\system\WCF;
4
5/**
6 * Contains user-related functions.
7 *
9f959ced 8 * @author Marcel Werk
ca4ba303 9 * @copyright 2001-2014 WoltLab GmbH
158bd3ca
TD
10 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
11 * @package com.woltlab.wcf
12 * @subpackage util
9f959ced 13 * @category Community Framework
158bd3ca 14 */
18284789 15final class UserUtil {
158bd3ca 16 /**
28410a97 17 * Returns true if the given name is a valid username.
158bd3ca 18 *
9f959ced
MS
19 * @param string $name
20 * @return boolean
158bd3ca
TD
21 */
22 public static function isValidUsername($name) {
988e0beb 23 // minimum length is 3 characters, maximum length is 255 characters
838e315b 24 if (mb_strlen($name) < 3 || mb_strlen($name) > 255) {
0d0de342
TD
25 return false;
26 }
27
158bd3ca
TD
28 // check illegal characters
29 if (!preg_match('!^[^,\n]+$!', $name)) {
30 return false;
31 }
32 // check long words
33 $words = preg_split('!\s+!', $name, -1, PREG_SPLIT_NO_EMPTY);
34 foreach ($words as $word) {
838e315b 35 if (mb_strlen($word) > 20) {
158bd3ca
TD
36 return false;
37 }
38 }
39 return true;
40 }
41
42 /**
28410a97 43 * Returns true if the given username is available.
158bd3ca 44 *
9f959ced
MS
45 * @param string $name
46 * @return boolean
158bd3ca
TD
47 */
48 public static function isAvailableUsername($name) {
39bea7dd
MS
49 $sql = "SELECT COUNT(username) AS count
50 FROM wcf".WCF_N."_user
51 WHERE username = ?";
158bd3ca
TD
52 $statement = WCF::getDB()->prepareStatement($sql);
53 $statement->execute(array($name));
54 $row = $statement->fetchArray();
55 return $row['count'] == 0;
56 }
9f959ced 57
158bd3ca 58 /**
28410a97 59 * Returns true if the given e-mail is a valid address.
0c166126 60 * @see http://www.faqs.org/rfcs/rfc821.html
158bd3ca
TD
61 *
62 * @param string $email
9f959ced 63 * @return boolean
158bd3ca
TD
64 */
65 public static function isValidEmail($email) {
66 // local-part
67 $c = '!#\$%&\'\*\+\-\/0-9=\?a-z\^_`\{\}\|~';
68 $string = '['.$c.']*(?:\\\\[\x00-\x7F]['.$c.']*)*';
69 $localPart = $string.'(?:\.'.$string.')*';
70
71 // domain
72 $name = '[a-z0-9](?:[a-z0-9-]*[a-z0-9])?';
73 $domain = $name.'(?:\.'.$name.')*\.[a-z]{2,}';
74
75 // mailbox
76 $mailbox = $localPart.'@'.$domain;
77
78 return preg_match('/^'.$mailbox.'$/i', $email);
79 }
80
81 /**
28410a97 82 * Returns true if the given email address is available.
158bd3ca 83 *
9f959ced
MS
84 * @param string $email
85 * @return boolean
158bd3ca
TD
86 */
87 public static function isAvailableEmail($email) {
39bea7dd
MS
88 $sql = "SELECT COUNT(email) AS count
89 FROM wcf".WCF_N."_user
90 WHERE email = ?";
158bd3ca
TD
91 $statement = WCF::getDB()->prepareStatement($sql);
92 $statement->execute(array($email));
93 $row = $statement->fetchArray();
94 return $row['count'] == 0;
95 }
96
97 /**
98 * Returns the user agent of the client.
99 *
100 * @return string
101 */
102 public static function getUserAgent() {
bc56f619
MW
103 if (isset($_SERVER['HTTP_USER_AGENT'])) {
104 $userAgent = $_SERVER['HTTP_USER_AGENT'];
105 if (!StringUtil::isASCII($userAgent) && !StringUtil::isUTF8($userAgent)) {
106 $userAgent = StringUtil::convertEncoding('ISO-8859-1', 'UTF-8', $userAgent);
107 }
108
109 return mb_substr($userAgent, 0, 255);
110 }
158bd3ca
TD
111 return '';
112 }
113
114 /**
1e5f194f 115 * Returns the ipv6 address of the client.
a17de04e 116 *
9f959ced 117 * @return string
158bd3ca
TD
118 */
119 public static function getIpAddress() {
120 $REMOTE_ADDR = '';
121 if (isset($_SERVER['REMOTE_ADDR'])) $REMOTE_ADDR = $_SERVER['REMOTE_ADDR'];
1e5f194f 122
158bd3ca
TD
123 // darwin fix
124 if ($REMOTE_ADDR == '::1' || $REMOTE_ADDR == 'fe80::1') {
92fd47d9 125 $REMOTE_ADDR = '127.0.0.1';
158bd3ca
TD
126 }
127
1e5f194f
MW
128 $REMOTE_ADDR = self::convertIPv4To6($REMOTE_ADDR);
129
158bd3ca
TD
130 return $REMOTE_ADDR;
131 }
132
1e5f194f
MW
133 /**
134 * Converts given ipv4 to ipv6.
135 *
136 * @param string $ip
137 * @return string
138 */
139 public static function convertIPv4To6($ip) {
827e7aea
AE
140 // drop Window's scope id (confused PHP)
141 $ip = preg_replace('~%[^%]+$~', '', $ip);
142
1e5f194f
MW
143 if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) {
144 // given ip is already ipv6
145 return $ip;
146 }
147
148 if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false) {
149 // invalid ip given
150 return '';
151 }
152
153 $ipArray = array_pad(explode('.', $ip), 4, 0);
154 $part7 = base_convert(($ipArray[0] * 256) + $ipArray[1], 10, 16);
155 $part8 = base_convert(($ipArray[2] * 256) + $ipArray[3], 10, 16);
6e1b461c 156
1e5f194f
MW
157 return '::ffff:'.$part7.':'.$part8;
158 }
159
9e7766a4
AE
160 /**
161 * Converts IPv6 embedded IPv4 address into IPv4 or returns input if true IPv6.
162 *
163 * @param string $ip
164 * @return string
165 */
166 public static function convertIPv6To4($ip) {
167 // validate if given IP is a proper IPv6 address
168 if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
169 // validate if given IP is a proper IPv4 address
170 if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false) {
9e7766a4
AE
171 // ip address is invalid
172 return '';
173 }
174
175 return $ip;
176 }
177
178 // check if ip is a masked IPv4 address
179 if (substr($ip, 0, 7) == '::ffff:') {
dd2dc943 180 $ip = substr($ip, 7);
6e1b461c 181 if (preg_match('~^([a-f0-9]{1,4}):([a-f0-9]{1,4})$~', $ip, $matches)) {
dd2dc943
AE
182 $ip = array(
183 base_convert($matches[1], 16, 10),
184 base_convert($matches[2], 16, 10)
185 );
186
187 $ipParts = array();
188 $tmp = $ip[0] % 256;
189 $ipParts[] = ($ip[0] - $tmp) / 256;
190 $ipParts[] = $tmp;
191 $tmp = $ip[1] % 256;
192 $ipParts[] = ($ip[1] - $tmp) / 256;
193 $ipParts[] = $tmp;
194
195 return implode('.', $ipParts);
196 }
197 else {
198 return $ip;
199 }
9e7766a4
AE
200 }
201 else {
202 // given ip is an IPv6 address and cannot be converted
203 return $ip;
204 }
205 }
206
158bd3ca
TD
207 /**
208 * Returns the request uri of the active request.
209 *
210 * @return string
211 */
212 public static function getRequestURI() {
213 $REQUEST_URI = '';
55a685d2 214
bf0436f9 215 $appendQueryString = true;
55a685d2
MW
216 if (!empty($_SERVER['ORIG_PATH_INFO']) && strpos($_SERVER['ORIG_PATH_INFO'], '.php') !== false) {
217 $REQUEST_URI = $_SERVER['ORIG_PATH_INFO'];
218 }
219 else if (!empty($_SERVER['ORIG_SCRIPT_NAME'])) {
220 $REQUEST_URI = $_SERVER['ORIG_SCRIPT_NAME'];
221 }
bf0436f9
AE
222 else if (!empty($_SERVER['SCRIPT_NAME']) && (isset($_SERVER['PATH_INFO']) && !empty($_SERVER['PATH_INFO']))) {
223 $REQUEST_URI = $_SERVER['SCRIPT_NAME'] . $_SERVER['PATH_INFO'];
224 }
225 else if (isset($_SERVER['REQUEST_URI']) && !empty($_SERVER['REQUEST_URI'])) {
226 $REQUEST_URI = $_SERVER['REQUEST_URI'];
227 $appendQueryString = false;
55a685d2
MW
228 }
229 else if (!empty($_SERVER['PHP_SELF'])) {
230 $REQUEST_URI = $_SERVER['PHP_SELF'];
231 }
232 else if (!empty($_SERVER['PATH_INFO'])) {
233 $REQUEST_URI = $_SERVER['PATH_INFO'];
234 }
bf0436f9 235 if ($appendQueryString && !empty($_SERVER['QUERY_STRING'])) {
55a685d2 236 $REQUEST_URI .= '?'.$_SERVER['QUERY_STRING'];
158bd3ca 237 }
158bd3ca 238
55a685d2
MW
239 // fix encoding
240 if (!StringUtil::isASCII($REQUEST_URI) && !StringUtil::isUTF8($REQUEST_URI)) {
241 $REQUEST_URI = StringUtil::convertEncoding('ISO-8859-1', 'UTF-8', $REQUEST_URI);
242 }
158bd3ca 243
838e315b 244 return mb_substr(FileUtil::unifyDirSeparator($REQUEST_URI), 0, 255);
158bd3ca 245 }
18284789
TD
246
247 private function __construct() { }
dcb3a44c 248}