. * */ namespace Vvveb\System\User; use function Vvveb\__; use function Vvveb\session as sess; use Vvveb\Sql\UserSQL; use Vvveb\System\PageCache; use Vvveb\System\Session; class User extends Auth { private static $namespace = 'user'; public static function add($data) { $user = new UserSQL(); if (! isset($data['username']) || ! $data['username']) { return false; } self::sanitize($data); //check if email or username is already registered $check = ['username'=> $data['username']]; if (isset($data['email'])) { $check['email'] = $data['email']; } if ($userInfo = $user->get($check)) { return $userInfo; } if (empty($data['password'])) { unset($data['password']); } else { $data['password'] = self :: password($data['password']); } $data['status'] = 1; //0 $data['last_ip'] = $_SERVER['REMOTE_ADDR'] ?? ''; return $user->add([self :: $namespace => $data]); } public static function update($data, $condition) { $user = new UserSQL(); if (empty($data['password'])) { unset($data['password']); } else { $data['password'] = self :: password($data['password']); } //$data['status'] = 0; self::sanitize($data); $data['updated_at'] = $data['updated_at'] ?? date('Y-m-d H:i:s', time()); return $user->edit(array_merge([self :: $namespace => $data], $condition)); } public static function get($data) { $user = new UserSQL(); //check user email and that status is active $loginInfo = []; //['status' => 1]; $userInfo = false; if (isset($data['email'])) { $loginInfo['email'] = $data['email']; } if (isset($data[self :: $namespace])) { $loginInfo['username'] = $data[self :: $namespace]; } if (isset($data['username'])) { $loginInfo['username'] = $data['username']; } if (isset($data['user_id'])) { $loginInfo['user_id'] = $data['user_id']; } if (isset($data['token'])) { $loginInfo['token'] = $data['token']; } if (isset($data['status'])) { $loginInfo['status'] = $data['status']; } $userInfo = $user->get($loginInfo); if (! $userInfo) { return []; } return $userInfo; } public static function login($data, $additionalInfo = [], &$feedback = []) { $data['status'] = 1; $userInfo = self::get($data); $passwordCorrect = false; $userExists = ($userInfo && isset($userInfo['password'])); if ($userExists) { $passwordCorrect = self::checkPassword($data['password'], $userInfo['password']); } if (! $userExists || ! $passwordCorrect) { if ($userExists) { $message = __('Password incorrect!'); $code = 0; } else { $message = __('User not found or has status inactive!'); $code = 1; } $feedback = ['message' => $message, 'code' => $code]; return false; } $session = Session :: getInstance(); $session->regenerateId(true); unset($userInfo['password']); $session->set(self :: $namespace, $userInfo + $additionalInfo); $lastIp = $_SERVER['REMOTE_ADDR'] ?? ''; self::update(['last_ip' => $lastIp], ['user_id' => $userInfo['user_id']]); PageCache::disable('user'); return $userInfo; } public static function logout() { PageCache::enable(self :: $namespace); return sess([self :: $namespace => false]); } public static function hash($data, $salt) { return hash_hmac('md5', $data, $salt); } public static function generateCookie($cookieValue) { list($value, $hash) = explode(':', $cookieValue, 2); if (md5($value . '-' . SECRET_KEY) == $hash) { return true; } else { return false; } } public static function checkCookie($cookieValue, $hmac, $scheme) { list($username, $hash, $expiration, $token) = explode('|', $cookieValue, 4); $key = hash($username . '|' . $hash . '|' . $expiration . '|' . $token, $scheme); $algo = function_exists('hash') ? 'sha256' : 'sha1'; $hash = hash_hmac($algo, $username . '|' . $expiration . '|' . $token, $key); $valid = hash_equals($hash, $hmac); return $valid; } /** * @ Currently logged in user data or empty array if guest * @return mixed */ public static function current() { $current = sess(self :: $namespace, []); if ($current) { PageCache::disable('user'); } else { PageCache::enable('user'); } return $current; } /** * @ Update user session data * @param mixed $data * * @return mixed */ public static function session($data) { $current = self :: current(); if ($current && $data && is_array($data)) { $current = array_merge($current, $data); return sess([self :: $namespace => $current]); } return false; } }