2016-11-29 22:27:19 +00:00
< ? php
2025-03-29 10:50:03 +00:00
2022-02-14 20:48:15 -08:00
/**
* Represents a user , logged in or not .
2017-03-16 19:05:52 +00:00
*
2022-02-14 20:48:15 -08:00
* @ package NamelessMC\Core
* @ author Samerton
* @ author Partydragen
* @ author Aberdeener
2024-03-31 20:19:43 +01:00
* @ version 2.2 . 0
2022-02-14 20:48:15 -08:00
* @ license MIT
2016-11-29 22:27:19 +00:00
*/
2024-03-09 03:19:55 -08:00
class User
{
2022-04-23 12:02:00 -07:00
private static array $_user_cache = [];
2023-03-23 20:01:23 -07:00
private static array $_group_cache = [];
private static array $_integration_cache = [];
2022-04-23 12:02:00 -07:00
2021-10-07 14:02:46 -07:00
private DB $_db ;
2021-10-08 20:12:07 +02:00
2022-02-14 20:48:15 -08:00
/**
2022-04-17 16:53:58 -07:00
* @ var UserData | null The user ' s data . Basically just the row from `nl2_users` where the user ID is the key .
2022-02-14 20:48:15 -08:00
*/
2022-04-17 16:53:58 -07:00
private ? UserData $_data ;
2022-02-14 20:48:15 -08:00
/**
2022-04-17 20:09:15 -07:00
* @ var array < int , Group > The user ' s groups .
2022-02-14 20:48:15 -08:00
*/
2023-03-23 20:01:23 -07:00
private array $_groups ;
2022-02-14 20:48:15 -08:00
2022-04-16 18:42:24 +02:00
/**
2022-04-17 16:53:58 -07:00
* @ var IntegrationUser [] The user ' s integrations .
2022-04-16 18:42:24 +02:00
*/
private array $_integrations ;
2022-03-29 16:22:34 -07:00
/**
2022-04-17 20:09:15 -07:00
* @ var Group The user ' s main group .
2022-03-29 16:22:34 -07:00
*/
2022-04-17 20:09:15 -07:00
private Group $_main_group ;
2022-03-29 16:22:34 -07:00
2022-02-14 20:48:15 -08:00
/**
* @ var array The user ' s placeholders .
*/
2021-11-02 22:34:16 -07:00
private array $_placeholders ;
2022-02-14 20:48:15 -08:00
/**
* @ var string The session name configuration value for remembering the user .
*/
2021-10-07 14:02:46 -07:00
private string $_sessionName ;
2022-02-14 20:48:15 -08:00
/**
* @ var string The cookie name configuration value .
*/
2021-10-07 14:02:46 -07:00
private string $_cookieName ;
2022-02-14 20:48:15 -08:00
/**
* @ var bool Whether this user is logged in or not .
*/
2021-10-07 14:02:46 -07:00
private bool $_isLoggedIn = false ;
2022-02-14 20:48:15 -08:00
/**
* @ var string The session name configuration value for remembering the admin user .
*/
2021-10-07 14:02:46 -07:00
private string $_admSessionName ;
2022-02-14 20:48:15 -08:00
/**
* @ var bool Whether this user is logged in as an admin or not .
*/
2021-10-07 14:02:46 -07:00
private bool $_isAdmLoggedIn = false ;
2025-03-29 10:50:03 +00:00
public function __construct ( ? string $user = null , string $field = 'id' )
2024-03-09 03:19:55 -08:00
{
2020-12-13 19:38:04 +01:00
$this -> _db = DB :: getInstance ();
2022-06-12 20:35:45 -06:00
$this -> _sessionName = Config :: get ( 'session.session_name' );
$this -> _cookieName = Config :: get ( 'remember.cookie_name' );
$this -> _admSessionName = Config :: get ( 'session.admin_name' );
2020-12-13 19:38:04 +01:00
2022-04-22 20:48:50 +02:00
if ( $user === null ) {
2020-12-13 19:38:04 +01:00
if ( Session :: exists ( $this -> _sessionName )) {
2022-08-13 06:29:09 +02:00
$hash = Session :: get ( $this -> _sessionName );
if ( $this -> find ( $hash , 'hash' )) {
2020-12-13 19:38:04 +01:00
$this -> _isLoggedIn = true ;
2024-10-17 23:21:27 -07:00
$this -> _db -> update ( 'users_session' , [ 'hash' , $hash ], [ 'last_seen' => date ( 'U' )]);
2020-12-13 19:38:04 +01:00
}
}
if ( Session :: exists ( $this -> _admSessionName )) {
2022-08-13 06:29:09 +02:00
$hash = Session :: get ( $this -> _admSessionName );
if ( $this -> find ( $hash , 'hash' )) {
2020-12-13 19:38:04 +01:00
$this -> _isAdmLoggedIn = true ;
2024-10-17 23:21:27 -07:00
$this -> _db -> update ( 'users_session' , [ 'hash' , $hash ], [ 'last_seen' => date ( 'U' )]);
2020-12-13 19:38:04 +01:00
}
}
} else {
$this -> find ( $user , $field );
}
}
2021-12-07 22:14:12 -08:00
/**
* Find a user by unique identifier ( username , ID , email , etc ) .
* Loads instance variables for this class .
*
2023-03-23 20:01:23 -07:00
* @ param string $value Unique identifier .
2021-12-07 22:14:12 -08:00
* @ param string $field What column to check for their unique identifier in .
*
* @ return bool True / false on success or failure respectfully .
*/
2024-03-09 03:19:55 -08:00
private function find ( string $value , string $field = 'id' ) : bool
{
2023-03-23 20:01:23 -07:00
if ( isset ( self :: $_user_cache [ " $value . $field " ])) {
$this -> _data = self :: $_user_cache [ " $value . $field " ];
2024-03-09 03:19:55 -08:00
2023-03-23 20:01:23 -07:00
return true ;
}
2021-12-07 22:14:12 -08:00
2023-03-23 20:01:23 -07:00
if ( $field !== 'hash' ) {
$data = $this -> _db -> get ( 'users' , [ $field , $value ]);
} else {
2024-10-17 23:21:27 -07:00
$data = $this -> _db -> query (
<<< 'SQL'
SELECT
nl2_users .*
FROM nl2_users
LEFT JOIN nl2_users_session
ON nl2_users . id = nl2_users_session . user_id
WHERE
nl2_users_session . hash = ?
AND nl2_users_session . active = 1
AND (
nl2_users_session . expires_at IS NULL
OR nl2_users_session . expires_at > ?
)
SQL ,
[
$value ,
time (),
]
);
2023-03-23 20:01:23 -07:00
}
2021-12-07 22:14:12 -08:00
2023-03-23 20:01:23 -07:00
if ( $data -> count ()) {
$this -> _data = new UserData ( $data -> first ());
self :: $_user_cache [ " $value . $field " ] = $this -> _data ;
2024-03-09 03:19:55 -08:00
2023-03-23 20:01:23 -07:00
return true ;
2021-12-07 22:14:12 -08:00
}
return false ;
}
/**
* Add a group to this user .
*
* @ param int $group_id ID of group to give .
2024-03-09 03:19:55 -08:00
* @ param int $expire Expiry in epoch time . If not supplied , group will never expire .
2021-12-07 22:14:12 -08:00
*
* @ return bool True on success , false if they already have it .
*/
2024-03-09 03:19:55 -08:00
public function addGroup ( int $group_id , int $expire = 0 ) : bool
{
2023-05-10 13:00:07 +02:00
if ( array_key_exists ( $group_id , $this -> getGroups ())) {
2021-12-07 22:14:12 -08:00
return false ;
}
2023-09-08 17:41:31 +02:00
$group = Group :: find ( $group_id );
if ( ! $group ) {
ErrorHandler :: logWarning ( 'Could not add invalid group ' . $group_id . ' to user ' . $this -> data () -> id );
2024-03-09 03:19:55 -08:00
2023-09-08 17:41:31 +02:00
return false ;
}
2023-03-23 20:01:23 -07:00
$this -> _db -> query ( 'INSERT INTO `nl2_users_groups` (`user_id`, `group_id`, `received`, `expire`) VALUES (?, ?, ?, ?)' , [
$this -> data () -> id ,
$group_id ,
date ( 'U' ),
2024-03-09 03:19:55 -08:00
$expire ,
2023-03-23 20:01:23 -07:00
]);
2023-09-08 17:41:31 +02:00
$this -> _groups [ $group_id ] = $group ;
self :: $_group_cache [ $this -> data () -> id ][ $group_id ] = $group ;
2021-12-07 22:14:12 -08:00
2023-03-01 11:35:10 -08:00
EventHandler :: executeEvent ( new UserGroupAddedEvent (
$this ,
$this -> _groups [ $group_id ],
));
2022-05-19 17:13:09 +02:00
2021-12-07 22:14:12 -08:00
return true ;
}
/**
2023-03-23 20:01:23 -07:00
* Get the user ' s data .
2021-12-07 22:14:12 -08:00
*
2022-04-17 16:53:58 -07:00
* @ return UserData This user ' s data .
2021-12-07 22:14:12 -08:00
*/
2024-03-09 03:19:55 -08:00
public function data () : ? UserData
{
2022-06-02 16:38:23 +01:00
return $this -> _data ? ? null ;
2021-12-07 22:14:12 -08:00
}
2021-04-12 18:36:34 -07:00
/**
2024-03-09 03:19:55 -08:00
* Get this user ' s main group CSS styling .
2021-04-12 18:36:34 -07:00
*
2022-03-29 16:22:34 -07:00
* @ return string The CSS styling .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function getGroupStyle () : string
{
2022-03-29 15:49:18 -07:00
$group = $this -> getMainGroup ();
2022-03-26 12:31:45 -07:00
2022-03-31 21:56:57 +02:00
$group_username_color = Output :: getClean ( $group -> group_username_color );
$group_username_css = Output :: getClean ( $group -> group_username_css );
2022-03-26 12:31:45 -07:00
2022-03-29 15:49:18 -07:00
$css = '' ;
if ( $group_username_color ) {
$css .= " color: $group_username_color ; " ;
}
if ( $group_username_css ) {
$css .= $group_username_css ;
2020-12-13 19:38:04 +01:00
}
2022-03-29 15:49:18 -07:00
return $css ;
2020-12-13 19:38:04 +01:00
}
2021-10-08 20:12:07 +02:00
2021-04-12 18:36:34 -07:00
/**
* Update a user ' s data in the database .
*
2024-03-09 03:19:55 -08:00
* @ param array $fields Column names and values to update .
2021-10-29 22:09:38 -07:00
* @ throws Exception
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function update ( array $fields = []) : void
{
2022-04-17 16:53:58 -07:00
if ( ! $this -> _db -> update ( 'users' , $this -> data () -> id , $fields )) {
2022-01-15 15:18:05 -08:00
throw new RuntimeException ( 'There was a problem updating your details.' );
2020-12-13 19:38:04 +01:00
}
}
2021-04-12 18:36:34 -07:00
/**
* Create a new user .
*
* @ param array $fields Column names and values to insert to database .
*/
2024-03-09 03:19:55 -08:00
public function create ( array $fields = []) : void
{
2020-12-13 19:38:04 +01:00
if ( ! $this -> _db -> insert ( 'users' , $fields )) {
2022-01-15 15:18:05 -08:00
throw new RuntimeException ( 'There was a problem creating an account.' );
2020-12-13 19:38:04 +01:00
}
}
2021-04-12 18:36:34 -07:00
/**
* Get a user ' s username from their ID .
*
2022-03-26 12:31:45 -07:00
* @ param int $id Their ID .
2021-10-08 20:12:07 +02:00
*
2022-03-26 12:31:45 -07:00
* @ return ? string Their username , null on failure .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function idToName ( int $id ) : ? string
{
2022-05-01 23:22:19 -07:00
$data = $this -> _db -> get ( 'users' , [ 'id' , $id ]);
2020-12-13 19:38:04 +01:00
2022-03-26 12:31:45 -07:00
if ( $data -> count ()) {
2023-03-23 20:01:23 -07:00
return $data -> first () -> username ;
2020-12-13 19:38:04 +01:00
}
2021-04-12 18:36:34 -07:00
2022-03-26 12:31:45 -07:00
return null ;
2020-12-13 19:38:04 +01:00
}
2021-04-12 18:36:34 -07:00
/**
* Get a user ' s nickname from their ID .
*
2022-03-26 12:31:45 -07:00
* @ param int $id Their ID .
2021-10-08 20:12:07 +02:00
*
2022-03-26 12:31:45 -07:00
* @ return ? string Their nickname , null on failure .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function idToNickname ( int $id ) : ? string
{
2022-05-01 23:22:19 -07:00
$data = $this -> _db -> get ( 'users' , [ 'id' , $id ]);
2020-12-13 19:38:04 +01:00
2022-03-26 12:31:45 -07:00
if ( $data -> count ()) {
2023-03-23 20:01:23 -07:00
return $data -> first () -> nickname ;
2020-12-13 19:38:04 +01:00
}
2021-04-12 18:36:34 -07:00
2022-03-26 12:31:45 -07:00
return null ;
2020-12-13 19:38:04 +01:00
}
2021-12-07 22:14:12 -08:00
/**
* Log the user in .
*
* @ param string | null $username Their username ( or email , depending on $method ) .
* @ param string | null $password Their password .
2024-03-09 03:19:55 -08:00
* @ param bool $remember Whether to keep them logged in or not .
* @ param string $method What column to check for their details in . Can be either `username` or `email` or `oauth` .
2021-12-07 22:14:12 -08:00
*
* @ return bool True / false on success or failure respectfully .
*/
2024-03-09 03:19:55 -08:00
public function login ( ? string $username = null , ? string $password = null , bool $remember = false , string $method = 'email' ) : bool
{
2021-12-07 22:14:12 -08:00
return $this -> _commonLogin ( $username , $password , $remember , $method , false );
}
2024-03-09 03:19:55 -08:00
private function _commonLogin ( ? string $username , ? string $password , bool $remember , string $method , bool $is_admin ) : bool
{
2021-10-08 11:19:01 -07:00
$sessionName = $is_admin ? $this -> _admSessionName : $this -> _sessionName ;
2022-08-13 06:29:09 +02:00
if ( ! $username && $method == 'hash' && $this -> exists ()) {
// Logged in using hash from cookie
Session :: put ( $sessionName , $password );
2021-10-08 20:12:07 +02:00
if ( ! $is_admin ) {
$this -> _isLoggedIn = true ;
}
2024-03-09 03:19:55 -08:00
} elseif ( $this -> checkCredentials ( $username , $password , $method ) === true ) {
2022-03-29 16:22:34 -07:00
// Valid credentials
2022-08-13 06:29:09 +02:00
$hash = SecureRandom :: alphanumeric ();
2024-10-17 23:21:27 -07:00
$expiresAt = $remember ? time () + Config :: get ( 'remember.cookie_expiry' ) : null ;
2017-05-12 17:13:46 +01:00
2022-08-13 06:29:09 +02:00
$this -> _db -> insert ( 'users_session' , [
'user_id' => $this -> data () -> id ,
'hash' => $hash ,
'remember_me' => $remember ,
2024-10-17 23:21:27 -07:00
'active' => true ,
2024-03-09 03:19:55 -08:00
'login_method' => $is_admin ? 'admin' : $method ,
2024-10-17 23:21:27 -07:00
'user_agent' => $_SERVER [ 'HTTP_USER_AGENT' ],
'ip' => HttpUtils :: getRemoteAddress (),
'expires_at' => $expiresAt ,
2022-08-13 06:29:09 +02:00
]);
Session :: put ( $sessionName , $hash );
2021-04-12 18:36:34 -07:00
2022-08-13 06:29:09 +02:00
if ( $remember ) {
2022-03-29 16:22:34 -07:00
$cookieName = $is_admin ? ( $this -> _cookieName . '_adm' ) : $this -> _cookieName ;
2024-10-17 23:21:27 -07:00
Cookie :: put ( $cookieName , $hash , $expiresAt , HttpUtils :: getProtocol () === 'https' , true , false );
2017-05-12 17:13:46 +01:00
}
2022-03-29 16:22:34 -07:00
return true ;
2020-12-13 19:38:04 +01:00
}
2021-04-12 18:36:34 -07:00
2020-12-13 19:38:04 +01:00
return false ;
}
2021-04-12 18:36:34 -07:00
/**
2021-12-07 22:14:12 -08:00
* Does this user exist ?
2021-10-08 20:12:07 +02:00
*
2021-12-07 22:14:12 -08:00
* @ return bool Whether the user exists ( has data ) or not .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function exists () : bool
{
2022-03-26 12:31:45 -07:00
return ! empty ( $this -> _data );
2020-12-13 19:38:04 +01:00
}
2017-03-16 19:05:52 +00:00
2021-04-12 18:36:34 -07:00
/**
* Check whether given credentials are valid .
*
* @ param string $username Username ( or email ) to check .
* @ param string $password Password entered by user .
2024-03-09 03:19:55 -08:00
* @ param string $method Column to search for user with . Can be `email` or `username` or `oauth` . If it is `oauth` , then the request will be granted .
2021-10-08 20:12:07 +02:00
*
2021-04-12 18:36:34 -07:00
* @ return bool True if correct , false otherwise .
*/
2024-03-09 03:19:55 -08:00
public function checkCredentials ( string $username , string $password , string $method = 'email' ) : bool
{
2022-03-29 16:22:34 -07:00
$user = $this -> find ( $username , $method === 'oauth' ? 'id' : $method );
2022-02-01 14:24:14 -08:00
2022-02-14 20:48:15 -08:00
if ( $method === 'oauth' ) {
2022-02-01 14:24:14 -08:00
return true ;
}
2020-12-06 20:23:23 -08:00
if ( $user ) {
2020-12-13 20:42:04 -08:00
switch ( $this -> data () -> pass_method ) {
2017-05-12 17:13:46 +01:00
case 'sha256' :
2022-03-10 12:32:04 -08:00
[ $salt , $pass ] = explode ( '$' , $this -> data () -> password );
2024-03-09 03:19:55 -08:00
2023-01-22 11:43:01 -08:00
return $salt . hash ( 'sha256' , hash ( 'sha256' , $password ) . $salt ) == $salt . $pass ;
2017-05-12 17:13:46 +01:00
case 'pbkdf2' :
2022-03-10 12:32:04 -08:00
[ $iterations , $salt , $pass ] = explode ( '$' , $this -> data () -> password );
2017-05-12 17:13:46 +01:00
$hashed = hash_pbkdf2 ( 'sha256' , $password , $salt , $iterations , 64 , true );
2024-03-09 03:19:55 -08:00
2023-01-22 11:43:01 -08:00
return $hashed == hex2bin ( $pass );
2017-05-12 17:13:46 +01:00
case 'modernbb' :
case 'sha1' :
2023-01-22 11:43:01 -08:00
return sha1 ( $password ) == $this -> data () -> password ;
2017-05-12 17:13:46 +01:00
default :
// Default to bcrypt
2023-01-22 11:43:01 -08:00
return password_verify ( $password , $this -> data () -> password );
2017-05-12 17:13:46 +01:00
}
}
return false ;
}
2020-12-13 19:38:04 +01:00
2021-12-07 22:14:12 -08:00
/**
* Handle StaffCP logins .
*
* @ param string | null $username Their username ( or email , depending on $method ) .
* @ param string | null $password Their password .
2024-03-09 03:19:55 -08:00
* @ param string $method What column to check for their details in . Can be either `username` or `email` .
2021-12-07 22:14:12 -08:00
*
* @ return bool True / false on success or failure respectfully .
*/
2024-03-09 03:19:55 -08:00
public function adminLogin ( ? string $username = null , ? string $password = null , string $method = 'email' ) : bool
{
2021-12-07 22:14:12 -08:00
return $this -> _commonLogin ( $username , $password , true , $method , true );
}
2021-04-12 18:36:34 -07:00
/**
* Get user ' s display name .
*
2024-03-09 03:19:55 -08:00
* @ param bool $username If true , will use their username . If false , will use their nickname .
2021-04-12 18:36:34 -07:00
* @ return string Their display name .
*/
2024-03-09 03:19:55 -08:00
public function getDisplayname ( bool $username = false ) : string
{
2021-04-12 18:36:34 -07:00
if ( $username ) {
2022-06-03 11:49:11 +01:00
return Output :: getClean ( $this -> data () -> username );
2020-12-13 19:38:04 +01:00
}
2021-10-08 20:12:07 +02:00
2022-06-03 11:49:11 +01:00
return Output :: getClean ( $this -> data () -> nickname );
2020-12-13 19:38:04 +01:00
}
2021-04-12 18:36:34 -07:00
/**
* Build this user ' s profile link .
*
* @ return string Compiled profile URL .
*/
2024-03-09 03:19:55 -08:00
public function getProfileURL () : string
{
2022-04-02 17:43:21 +02:00
return URL :: build ( '/profile/' . urlencode ( $this -> data () -> username ));
2020-12-13 19:38:04 +01:00
}
2021-04-12 18:36:34 -07:00
/**
2022-05-08 22:48:44 -06:00
* Get all of a user ' s groups id . Logged out / non - existent users will return just `0` .
2021-04-12 18:36:34 -07:00
*
2021-12-07 22:14:12 -08:00
* @ return array Array of all their group IDs .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function getAllGroupIds () : array
{
2022-01-21 19:13:56 +01:00
if ( ! $this -> exists ()) {
2022-04-17 16:53:58 -07:00
return [ 0 => 0 ];
2021-12-07 22:14:12 -08:00
}
2021-10-29 22:00:05 -07:00
$groups = [];
2023-03-23 20:01:23 -07:00
foreach ( $this -> getGroups () as $group ) {
$groups [ $group -> id ] = $group -> id ;
2020-12-13 19:38:04 +01:00
}
2021-10-08 20:12:07 +02:00
2020-10-26 20:04:58 +01:00
return $groups ;
}
2021-10-08 20:12:07 +02:00
2021-04-12 18:36:34 -07:00
/**
2021-12-07 22:14:12 -08:00
* Get if this user is currently logged in or not .
2021-10-08 20:12:07 +02:00
*
2021-12-07 22:14:12 -08:00
* @ return bool Whether they ' re logged in .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function isLoggedIn () : bool
{
2021-12-07 22:14:12 -08:00
return $this -> _isLoggedIn ;
}
2021-04-24 14:13:16 +01:00
2021-12-07 22:14:12 -08:00
/**
2022-03-29 16:22:34 -07:00
* Get all of a user ' s group HTML display code .
2021-12-07 22:14:12 -08:00
*
2022-03-29 16:22:34 -07:00
* @ return array Array of all their groups HTML .
2021-12-07 22:14:12 -08:00
*/
2024-03-09 03:19:55 -08:00
public function getAllGroupHtml () : array
{
2021-10-29 22:00:05 -07:00
$groups = [];
2021-04-12 18:36:34 -07:00
2023-03-23 20:01:23 -07:00
foreach ( $this -> getGroups () as $group ) {
$groups [] = $group -> group_html ;
2020-12-13 19:38:04 +01:00
}
2021-04-12 18:36:34 -07:00
return $groups ;
2020-12-13 19:38:04 +01:00
}
2021-04-12 18:36:34 -07:00
/**
* Get this user ' s signature .
*
* @ return string Their signature .
*/
2024-03-09 03:19:55 -08:00
public function getSignature () : string
{
2022-03-29 16:22:34 -07:00
return $this -> data () -> signature ? ? '' ;
2020-12-13 19:38:04 +01:00
}
2021-04-12 18:36:34 -07:00
/**
* Get this user ' s avatar .
*
2024-03-09 03:19:55 -08:00
* @ param int $size Size of image to render in pixels .
2021-05-08 15:07:07 -07:00
* @ param bool $full Whether to use full site URL or not , for external loading - ie discord webhooks .
2021-10-08 20:12:07 +02:00
*
2021-04-12 18:36:34 -07:00
* @ return string URL to their avatar image .
*/
2024-03-09 03:19:55 -08:00
public function getAvatar ( int $size = 128 , bool $full = false ) : string
{
2023-03-23 20:01:23 -07:00
$data_obj = new stdClass ();
// Convert UserData object to stdClass so we can dynamically add the 'uuid' property
foreach ( get_object_vars ( $this -> data ()) as $key => $value ) {
$data_obj -> { $key } = $value ;
}
2022-04-16 18:42:24 +02:00
$integrationUser = $this -> getIntegration ( 'Minecraft' );
if ( $integrationUser != null ) {
2022-04-17 16:53:58 -07:00
$data_obj -> uuid = $integrationUser -> data () -> identifier ;
2022-04-16 18:42:24 +02:00
} else {
2022-04-17 16:53:58 -07:00
$data_obj -> uuid = '' ;
2022-04-16 18:42:24 +02:00
}
2022-04-17 16:53:58 -07:00
return AvatarSource :: getAvatarFromUserData ( $data_obj , $this -> hasPermission ( 'usercp.gif_avatar' ), $size , $full );
2020-12-13 19:38:04 +01:00
}
2021-12-07 22:14:12 -08:00
/**
2022-02-14 20:48:15 -08:00
* Does the user have a specific permission in any of their groups ?
2021-12-07 22:14:12 -08:00
*
* @ param string $permission Permission node to check recursively for .
*
* @ return bool Whether they inherit this permission or not .
*/
2024-03-09 03:19:55 -08:00
public function hasPermission ( string $permission ) : bool
{
2023-03-23 20:01:23 -07:00
if ( ! $this -> exists ()) {
2021-12-24 22:48:47 -08:00
return false ;
}
2023-03-23 20:01:23 -07:00
foreach ( $this -> getGroups () as $group ) {
2022-04-17 21:05:14 -07:00
$permissions = json_decode ( $group -> permissions , true ) ? ? [];
2021-12-07 22:14:12 -08:00
2022-01-21 19:13:56 +01:00
if ( isset ( $permissions [ 'administrator' ]) && $permissions [ 'administrator' ] == 1 ) {
return true ;
}
2021-12-07 22:14:12 -08:00
2022-01-21 19:13:56 +01:00
if ( isset ( $permissions [ $permission ]) && $permissions [ $permission ] == 1 ) {
return true ;
2021-12-07 22:14:12 -08:00
}
}
return false ;
}
2024-10-17 23:21:27 -07:00
public function getActiveSessions () : array
{
return DB :: getInstance () -> query (
'SELECT * FROM nl2_users_session WHERE user_id = ? AND active = 1 ORDER BY last_seen DESC' ,
[
$this -> data () -> id ,
]
) -> results ();
}
/**
* Log the user out from a selected session .
*
* @ param string $sessionId Selected session ID .
*
* @ return void
*/
public function logoutSessionById ( string $sessionId ) : void
{
DB :: getInstance () -> query ( 'UPDATE nl2_users_session SET `active` = 0 WHERE user_id = ? AND id = ?' , [
$this -> data () -> id ,
$sessionId ,
]);
}
2022-08-13 06:29:09 +02:00
/**
* Log the user out from all other sessions .
*/
2024-03-09 03:19:55 -08:00
public function logoutAllOtherSessions () : void
{
2022-08-13 06:29:09 +02:00
DB :: getInstance () -> query ( 'UPDATE nl2_users_session SET `active` = 0 WHERE user_id = ? AND hash != ?' , [
$this -> data () -> id ,
2024-03-09 03:19:55 -08:00
Session :: get ( Config :: get ( 'session.session_name' )),
2022-08-13 06:29:09 +02:00
]);
}
2021-04-12 18:36:34 -07:00
/**
* Log the user out .
* Deletes their cookies , sessions and database session entry .
*/
2024-03-09 03:19:55 -08:00
public function logout () : void
{
2022-08-13 06:29:09 +02:00
$this -> _db -> update ( 'users_session' , [[ 'user_id' , $this -> data () -> id ], [ 'hash' , Session :: get ( $this -> _sessionName )]], [
2024-03-09 03:19:55 -08:00
'active' => 0 ,
2022-08-13 06:29:09 +02:00
]);
2020-12-13 19:38:04 +01:00
Session :: delete ( $this -> _sessionName );
Cookie :: delete ( $this -> _cookieName );
}
2021-10-08 20:12:07 +02:00
2021-04-12 18:36:34 -07:00
/**
2024-03-09 03:19:55 -08:00
* Process logout if user is admin .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function admLogout () : void
{
2022-08-13 06:29:09 +02:00
$this -> _db -> update ( 'users_session' , [[ 'user_id' , $this -> data () -> id ], [ 'hash' , Session :: get ( $this -> _admSessionName )]], [
2024-03-09 03:19:55 -08:00
'active' => 0 ,
2022-08-13 06:29:09 +02:00
]);
2020-12-13 19:38:04 +01:00
Session :: delete ( $this -> _admSessionName );
2021-04-12 18:36:34 -07:00
Cookie :: delete ( $this -> _cookieName . '_adm' );
2020-12-13 19:38:04 +01:00
}
2021-10-08 20:12:07 +02:00
2021-04-12 18:36:34 -07:00
/**
2022-04-16 18:42:24 +02:00
* Get the user ' s groups .
2021-04-12 18:36:34 -07:00
*
2023-03-23 20:01:23 -07:00
* @ return array < int , Group > Their groups .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function getGroups () : array
{
2023-03-23 20:01:23 -07:00
if ( isset ( $this -> _groups )) {
return $this -> _groups ;
}
if ( isset ( self :: $_group_cache [ $this -> data () -> id ])) {
2023-06-19 19:47:40 +02:00
$this -> _groups = self :: $_group_cache [ $this -> data () -> id ];
2023-03-23 20:01:23 -07:00
} else {
$groups_query = $this -> _db -> query ( 'SELECT nl2_groups.* FROM nl2_users_groups INNER JOIN nl2_groups ON group_id = nl2_groups.id WHERE user_id = ? AND deleted = 0 ORDER BY `order`' , [ $this -> data () -> id ]);
if ( $groups_query -> count ()) {
2023-06-19 19:47:40 +02:00
foreach ( $groups_query -> results () as $item ) {
$this -> _groups [ $item -> id ] = new Group ( $item );
}
2023-03-23 20:01:23 -07:00
} else {
2023-06-19 19:47:40 +02:00
$this -> _groups = [];
2023-03-23 20:01:23 -07:00
}
2023-06-19 19:47:40 +02:00
self :: $_group_cache [ $this -> data () -> id ] = $this -> _groups ;
2023-03-23 20:01:23 -07:00
}
2023-06-19 19:47:40 +02:00
if ( ! count ( $this -> _groups )) {
2023-03-23 20:01:23 -07:00
// Get default group
$default_group = Group :: find ( 1 , 'default_group' );
$default_group_id = $default_group -> id ? ? 1 ;
$this -> addGroup ( $default_group_id );
}
2021-12-07 22:14:12 -08:00
return $this -> _groups ;
2020-12-13 19:38:04 +01:00
}
2022-04-16 18:42:24 +02:00
/**
* Get the user ' s integrations .
*
2022-04-17 16:53:58 -07:00
* @ return IntegrationUser [] Their integrations .
2022-04-16 18:42:24 +02:00
*/
2024-03-09 03:19:55 -08:00
public function getIntegrations () : array
{
2023-03-23 20:01:23 -07:00
if ( isset ( $this -> _integrations )) {
return $this -> _integrations ;
}
$integrations = Integrations :: getInstance ();
2022-04-16 18:42:24 +02:00
2023-03-23 20:01:23 -07:00
if ( isset ( self :: $_integration_cache [ $this -> data () -> id ])) {
$integrations_query = self :: $_integration_cache [ $this -> data () -> id ];
} else {
2025-07-05 15:36:58 -07:00
$integrations_query = $this -> _db -> query ( 'SELECT nl2_users_integrations.*, nl2_integrations.name as integration_name FROM nl2_users_integrations LEFT JOIN nl2_integrations ON integration_id = nl2_integrations.id WHERE user_id = ?' , [ $this -> data () -> id ]);
2022-04-16 18:42:24 +02:00
if ( $integrations_query -> count ()) {
$integrations_query = $integrations_query -> results ();
2023-03-23 20:01:23 -07:00
} else {
$integrations_query = [];
}
self :: $_integration_cache [ $this -> data () -> id ] = $integrations_query ;
}
2022-04-16 18:42:24 +02:00
2023-03-23 20:01:23 -07:00
$integrations_list = [];
foreach ( $integrations_query as $item ) {
$integration = $integrations -> getIntegration ( $item -> integration_name );
if ( $integration != null ) {
$integrationUser = new IntegrationUser ( $integration , $this -> data () -> id , 'user_id' , $item );
2022-04-16 18:42:24 +02:00
2023-03-23 20:01:23 -07:00
$integrations_list [ $item -> integration_name ] = $integrationUser ;
2022-04-16 18:42:24 +02:00
}
2023-03-23 20:01:23 -07:00
}
2022-04-16 18:42:24 +02:00
2023-03-23 20:01:23 -07:00
return $this -> _integrations = $integrations_list ;
2022-04-16 18:42:24 +02:00
}
/**
* Get the user ' s integration .
*
* @ param string $integrationName Integration name
*
* @ return IntegrationUser | null Their integration user if connected otherwise null .
*/
2024-03-09 03:19:55 -08:00
public function getIntegration ( string $integrationName ) : ? IntegrationUser
{
2022-04-17 21:05:14 -07:00
return $this -> getIntegrations ()[ $integrationName ] ? ? null ;
2022-04-16 18:42:24 +02:00
}
2021-04-12 18:36:34 -07:00
/**
2023-03-23 20:01:23 -07:00
* Get the users placeholders .
2021-10-08 20:12:07 +02:00
*
2021-05-14 10:35:30 -07:00
* @ return array Their placeholders .
*/
2024-03-09 03:19:55 -08:00
public function getPlaceholders () : array
{
2023-03-23 20:01:23 -07:00
if ( isset ( $this -> _placeholders )) {
return $this -> _placeholders ;
}
2021-11-02 22:34:16 -07:00
2023-03-23 20:01:23 -07:00
$integrationUser = $this -> getIntegration ( 'Minecraft' );
if ( $integrationUser !== null ) {
return $this -> _placeholders = Placeholders :: getInstance () -> loadUserPlaceholders ( $integrationUser -> data () -> identifier );
}
return [];
2021-05-14 10:35:30 -07:00
}
/**
* Get this user ' s placeholders to display on their forum posts .
2021-10-08 20:12:07 +02:00
*
2021-05-14 10:35:30 -07:00
* @ return array Forum placeholders .
*/
2024-03-09 03:19:55 -08:00
public function getForumPlaceholders () : array
{
2021-11-02 22:34:16 -07:00
return array_filter ( $this -> getPlaceholders (), static function ( $placeholder ) {
2021-05-14 10:35:30 -07:00
return $placeholder -> show_on_forum ;
});
}
2023-03-23 20:01:23 -07:00
/**
* Get this user ' s placeholders to display on their profile .
*
* @ return array Profile placeholders .
*/
2024-03-09 03:19:55 -08:00
public function getProfilePlaceholders () : array
{
2023-03-23 20:01:23 -07:00
return array_filter ( $this -> getPlaceholders (), static function ( $placeholder ) {
return $placeholder -> show_on_profile ;
});
}
2021-04-12 18:36:34 -07:00
/**
* Get this user ' s main group ( with highest order ) .
*
2022-04-17 20:09:15 -07:00
* @ return Group The group
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function getMainGroup () : Group
{
2023-03-23 20:01:23 -07:00
return $this -> _main_group ? ? = array_reduce ( $this -> getGroups (), static function ( ? Group $carry , Group $group ) {
2022-03-29 16:22:34 -07:00
return $carry === null || $carry -> order > $group -> order ? $group : $carry ;
});
2020-12-13 19:38:04 +01:00
}
2021-10-08 20:12:07 +02:00
2021-04-12 18:36:34 -07:00
/**
2024-03-09 03:19:55 -08:00
* Set a group to user and remove all other groups .
2021-04-12 18:36:34 -07:00
*
2024-03-09 03:19:55 -08:00
* @ param int $group_id ID of group to set as main group .
* @ param int $expire Expiry in epoch time . If not supplied , group will never expire .
2021-10-29 22:09:38 -07:00
* @ return false | void
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function setGroup ( int $group_id , int $expire = 0 )
{
2023-09-08 17:41:31 +02:00
$group = Group :: find ( $group_id );
if ( ! $group ) {
ErrorHandler :: logWarning ( 'Could not set invalid group ' . $group_id . ' to user ' . $this -> data () -> id );
2024-03-09 03:19:55 -08:00
2023-09-08 17:41:31 +02:00
return false ;
}
2021-05-27 18:21:49 +02:00
if ( $this -> data () -> id == 1 ) {
return false ;
}
2023-03-23 20:01:23 -07:00
2022-05-01 23:16:22 -07:00
$this -> _db -> query ( 'DELETE FROM `nl2_users_groups` WHERE `user_id` = ?' , [ $this -> data () -> id ]);
2020-12-13 19:48:20 +01:00
2023-03-23 20:01:23 -07:00
$this -> _db -> query ( 'INSERT INTO `nl2_users_groups` (`user_id`, `group_id`, `received`, `expire`) VALUES (?, ?, ?, ?)' , [
$this -> data () -> id ,
$group_id ,
date ( 'U' ),
2024-03-09 03:19:55 -08:00
$expire ,
2023-03-23 20:01:23 -07:00
]);
2021-10-08 20:12:07 +02:00
2021-10-29 22:00:05 -07:00
$this -> _groups = [];
2023-09-08 17:41:31 +02:00
$this -> _groups [ $group_id ] = $group ;
self :: $_group_cache [ $this -> data () -> id ] = $this -> _groups ;
2020-12-13 19:48:20 +01:00
}
2021-04-12 18:36:34 -07:00
/**
* Remove a group from the user .
*
2021-10-29 22:09:38 -07:00
* @ param int | null $group_id ID of group to remove .
2021-10-08 20:12:07 +02:00
*
2021-04-12 18:36:34 -07:00
* @ return bool Returns false if they did not have this group or the admin group is being removed from root user
*/
2024-03-09 03:19:55 -08:00
public function removeGroup ( ? int $group_id ) : bool
{
2023-03-23 20:01:23 -07:00
if ( ! array_key_exists ( $group_id , $this -> getGroups ())) {
2021-04-12 18:36:34 -07:00
return false ;
}
2021-02-24 10:37:51 -08:00
2021-04-12 18:36:34 -07:00
if ( $group_id == 2 && $this -> data () -> id == 1 ) {
return false ;
2020-12-13 19:38:04 +01:00
}
2021-02-24 10:37:51 -08:00
2023-03-23 20:01:23 -07:00
$this -> _db -> query ( 'DELETE FROM `nl2_users_groups` WHERE `user_id` = ? AND `group_id` = ?' , [
$this -> data () -> id ,
2024-03-09 03:19:55 -08:00
$group_id ,
2023-03-23 20:01:23 -07:00
]);
2021-10-08 20:12:07 +02:00
2023-03-01 11:35:10 -08:00
EventHandler :: executeEvent ( new UserGroupRemovedEvent (
$this ,
$this -> _groups [ $group_id ],
));
2022-05-19 17:13:09 +02:00
2021-08-29 15:43:37 +02:00
unset ( $this -> _groups [ $group_id ]);
2023-06-19 19:47:40 +02:00
unset ( self :: $_group_cache [ $this -> data () -> id ][ $group_id ]);
2021-04-12 18:36:34 -07:00
return true ;
2020-12-13 19:38:04 +01:00
}
2021-04-12 18:36:34 -07:00
/**
* Get if this user is active / validated or not .
*
* @ return bool Whether this user has been validated / activated .
*/
2024-03-09 03:19:55 -08:00
public function isValidated () : bool
{
2020-12-13 14:32:03 -08:00
return $this -> data () -> active ;
}
2021-04-12 18:36:34 -07:00
/**
2025-05-15 11:24:55 -07:00
* Get a comma separated string of all other users who have not blocked this user .
2021-04-12 18:36:34 -07:00
* For the new private message dropdown .
*
2022-05-21 15:59:20 -06:00
* @ return array Array of usernames .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function listAllOtherUsers () : array
{
2025-05-15 11:24:55 -07:00
$data = $this -> _db -> query (
'SELECT u.username FROM nl2_users u WHERE u.id <> ? AND u.id NOT IN (SELECT user_id FROM nl2_blocked_users bu WHERE bu.user_blocked_id = ?)' ,
[ $this -> data () -> id , $this -> data () -> id ]
) -> results ();
2022-05-21 15:59:20 -06:00
$return = [];
2020-12-13 19:38:04 +01:00
foreach ( $data as $item ) {
2022-05-21 15:59:20 -06:00
$return [] = $item -> username ;
2020-12-13 19:38:04 +01:00
}
2021-10-08 20:12:07 +02:00
2022-05-21 15:59:20 -06:00
return $return ;
2020-12-13 19:38:04 +01:00
}
2021-10-08 20:12:07 +02:00
2021-04-12 18:36:34 -07:00
/**
* Return an ID from a username .
*
2022-03-26 12:31:45 -07:00
* @ param string $username Username to get ID for .
2021-10-08 20:12:07 +02:00
*
2022-03-26 12:31:45 -07:00
* @ return ? int ID on success , null on failure .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function nameToId ( string $username ) : ? int
{
2022-05-01 23:22:19 -07:00
$data = $this -> _db -> get ( 'users' , [ 'username' , $username ]);
2020-12-13 19:38:04 +01:00
2022-03-26 12:31:45 -07:00
if ( $data -> count ()) {
2023-03-23 20:01:23 -07:00
return $data -> first () -> id ;
2020-12-13 19:38:04 +01:00
}
2021-10-08 20:12:07 +02:00
2022-03-26 12:31:45 -07:00
return null ;
2020-12-13 19:38:04 +01:00
}
2017-03-16 19:05:52 +00:00
2021-04-12 18:36:34 -07:00
/**
* Return an ID from an email .
*
2024-03-09 03:19:55 -08:00
* @ param string $email Email to get ID for .
* @ return ? int ID on success , false on failure .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function emailToId ( string $email ) : ? int
{
2022-05-01 23:22:19 -07:00
$data = $this -> _db -> get ( 'users' , [ 'email' , $email ]);
2018-04-03 12:36:35 +01:00
2022-03-26 12:31:45 -07:00
if ( $data -> count ()) {
2023-03-23 20:01:23 -07:00
return $data -> first () -> id ;
2018-04-03 12:36:35 +01:00
}
2021-10-08 20:12:07 +02:00
2022-03-26 12:31:45 -07:00
return null ;
2020-11-05 19:52:16 +01:00
}
2021-10-08 20:12:07 +02:00
2021-04-12 18:36:34 -07:00
/**
* Get a list of PMs a user has access to .
*
2024-03-09 03:19:55 -08:00
* @ param int $user_id ID of user to get PMs for .
2022-03-26 12:31:45 -07:00
* @ return array Array of PMs .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function listPMs ( int $user_id ) : array
{
2022-03-26 12:31:45 -07:00
$return = []; // Array to return containing info of PMs
2020-12-13 19:38:04 +01:00
2022-03-26 12:31:45 -07:00
// Get a list of PMs which the user is in
2022-05-01 23:22:19 -07:00
$data = $this -> _db -> get ( 'private_messages_users' , [ 'user_id' , $user_id ]);
2020-12-13 19:38:04 +01:00
2022-03-26 12:31:45 -07:00
if ( $data -> count ()) {
$data = $data -> results ();
foreach ( $data as $result ) {
// Get a list of users who are in this conversation and return them as an array
2022-05-01 23:22:19 -07:00
$pms = $this -> _db -> get ( 'private_messages_users' , [ 'pm_id' , $result -> pm_id ]) -> results ();
2022-03-26 12:31:45 -07:00
$users = []; // Array containing users with permission
foreach ( $pms as $pm ) {
$users [] = $pm -> user_id ;
}
2020-12-13 19:38:04 +01:00
2022-03-26 12:31:45 -07:00
// Get the PM data
2022-05-01 23:22:19 -07:00
$pm = $this -> _db -> get ( 'private_messages' , [ 'id' , $result -> pm_id ]) -> first ();
2020-12-13 19:38:04 +01:00
2022-03-26 12:31:45 -07:00
$return [ $pm -> id ][ 'id' ] = $pm -> id ;
2022-04-21 22:25:06 +02:00
$return [ $pm -> id ][ 'title' ] = $pm -> title ;
2022-03-26 12:31:45 -07:00
$return [ $pm -> id ][ 'created' ] = $pm -> created ;
$return [ $pm -> id ][ 'updated' ] = $pm -> last_reply_date ;
$return [ $pm -> id ][ 'user_updated' ] = $pm -> last_reply_user ;
$return [ $pm -> id ][ 'users' ] = $users ;
2020-12-13 19:38:04 +01:00
}
}
2021-04-12 18:36:34 -07:00
2022-03-26 12:31:45 -07:00
// Order the PMs by date updated - most recent first
usort ( $return , static function ( $a , $b ) {
return $b [ 'updated' ] - $a [ 'updated' ];
});
return $return ;
2020-12-13 19:38:04 +01:00
}
2021-10-08 20:12:07 +02:00
2021-04-12 18:36:34 -07:00
/**
2024-03-09 03:19:55 -08:00
* Get a specific private message , and see if the user actually has permission to view it .
2021-04-12 18:36:34 -07:00
*
2024-03-09 03:19:55 -08:00
* @ param int $pm_id ID of PM to find .
* @ param int $user_id ID of user to check permission for .
2022-03-26 12:31:45 -07:00
* @ return array | null Array of info about PM , null on failure .
*/
2024-03-09 03:19:55 -08:00
public function getPM ( int $pm_id , int $user_id ) : ? array
{
2022-03-26 12:31:45 -07:00
// Get the PM - is the user the author?
2022-05-01 23:22:19 -07:00
$data = $this -> _db -> get ( 'private_messages' , [ 'id' , $pm_id ]);
2022-03-26 12:31:45 -07:00
if ( $data -> count ()) {
2023-03-23 20:01:23 -07:00
$data = $data -> first ();
2022-03-26 12:31:45 -07:00
// Does the user have permission to view the PM?
2022-05-01 23:22:19 -07:00
$pms = $this -> _db -> get ( 'private_messages_users' , [ 'pm_id' , $pm_id ]) -> results ();
2022-03-26 12:31:45 -07:00
foreach ( $pms as $pm ) {
if ( $pm -> user_id == $user_id ) {
$has_permission = true ;
$pm_user_id = $pm -> id ;
break ;
2020-12-13 19:38:04 +01:00
}
2022-03-26 12:31:45 -07:00
}
2020-12-13 19:38:04 +01:00
2022-03-26 12:31:45 -07:00
if ( ! isset ( $has_permission )) {
return null ; // User doesn't have permission
}
2020-12-13 19:38:04 +01:00
2022-03-26 12:31:45 -07:00
// Set message to "read"
if ( $pm -> read == 0 ) {
$this -> _db -> update ( 'private_messages_users' , $pm_user_id , [
2022-05-31 11:29:47 -06:00
'read' => true ,
2022-03-26 12:31:45 -07:00
]);
}
2020-12-13 19:38:04 +01:00
2022-03-26 12:31:45 -07:00
// User has permission, return the PM information
$users = []; // Array to store users
foreach ( $pms as $pm ) {
$users [] = $pm -> user_id ;
2020-12-13 19:38:04 +01:00
}
2022-03-26 12:31:45 -07:00
return [ $data , $users ];
2020-12-13 19:38:04 +01:00
}
2021-04-12 18:36:34 -07:00
2022-03-26 12:31:45 -07:00
return null ;
2020-12-13 19:38:04 +01:00
}
2021-10-08 20:12:07 +02:00
2021-04-12 18:36:34 -07:00
/**
* Check the user ' s permission to see if they can view this staffCP page or not .
* If they cannot , this will handle appropriate redirection .
*
2024-03-09 03:19:55 -08:00
* @ param string | null $permission Permission required for this page .
2021-10-29 22:09:38 -07:00
* @ return bool
2021-04-12 18:36:34 -07:00
*/
2025-03-29 10:50:03 +00:00
public function handlePanelPageLoad ( ? string $permission = null ) : bool
2024-03-09 03:19:55 -08:00
{
2021-10-09 16:40:07 +01:00
// Set page user is trying to access in session, to allow for redirection post-auth
if ( FRIENDLY_URLS === true ) {
$split = explode ( '?' , $_SERVER [ 'REQUEST_URI' ]);
2021-12-07 22:14:12 -08:00
if ( $split != null && count ( $split ) > 1 ) {
2021-10-09 16:40:07 +01:00
$_SESSION [ 'last_page' ] = URL :: build ( $split [ 0 ], $split [ 1 ]);
2021-12-07 22:14:12 -08:00
} else {
2021-10-09 16:40:07 +01:00
$_SESSION [ 'last_page' ] = URL :: build ( $split [ 0 ]);
2021-12-07 22:14:12 -08:00
}
2022-05-05 21:54:06 +02:00
if ( defined ( 'CONFIG_PATH' )) {
$_SESSION [ 'last_page' ] = substr ( $_SESSION [ 'last_page' ], strlen ( CONFIG_PATH ));
}
2021-12-07 22:14:12 -08:00
} else {
2021-10-09 16:40:07 +01:00
$_SESSION [ 'last_page' ] = URL :: build ( $_GET [ 'route' ]);
2021-12-07 22:14:12 -08:00
}
2021-10-09 16:40:07 +01:00
2020-12-18 20:23:06 -08:00
if ( ! $this -> isLoggedIn ()) {
Redirect :: to ( URL :: build ( '/login' ));
}
2021-05-12 11:55:20 -05:00
if ( ! $this -> canViewStaffCP ()) {
2020-12-18 20:23:06 -08:00
Redirect :: to ( URL :: build ( '/' ));
}
if ( ! $this -> isAdmLoggedIn ()) {
Redirect :: to ( URL :: build ( '/panel/auth' ));
}
2022-01-15 15:18:05 -08:00
return ! ( $permission != null && ! $this -> hasPermission ( $permission ));
2020-12-18 20:23:06 -08:00
}
2021-12-07 22:14:12 -08:00
/**
* Can the specified user view StaffCP ?
*
* @ return bool Whether they can view it or not .
*/
2024-03-09 03:19:55 -08:00
public function canViewStaffCP () : bool
{
2023-03-23 20:01:23 -07:00
foreach ( $this -> getGroups () as $group ) {
if ( $group -> admin_cp == 1 ) {
return true ;
2021-12-07 22:14:12 -08:00
}
}
return false ;
}
/**
* Get if the current user is authenticated as an administrator .
*
* @ return bool Whether they ' re logged in as admin .
*/
2024-03-09 03:19:55 -08:00
public function isAdmLoggedIn () : bool
{
2021-12-07 22:14:12 -08:00
return $this -> _isAdmLoggedIn ;
}
2021-04-12 18:36:34 -07:00
/**
2024-03-09 03:19:55 -08:00
* Get profile fields for this user .
2021-04-12 18:36:34 -07:00
*
2022-04-18 10:33:18 -07:00
* @ param bool $show_private Whether to only return public fields or not ( default `true` ) .
2024-03-09 03:19:55 -08:00
* @ param bool $only_forum Whether to only return fields which display on forum posts , only if $public is true ( default `false` ) .
2021-10-08 20:12:07 +02:00
*
2022-04-18 10:33:18 -07:00
* @ return array < int , UserProfileField > Array of profile fields .
2021-04-12 18:36:34 -07:00
*/
2024-03-09 03:19:55 -08:00
public function getProfileFields ( bool $show_private = false , bool $only_forum = false ) : array
{
2022-05-11 11:45:20 +02:00
$rows = DB :: getInstance () -> query ( 'SELECT pf.*, upf.id as upf_id, upf.value, upf.updated FROM nl2_profile_fields pf LEFT JOIN nl2_users_profile_fields upf ON (pf.id = upf.field_id AND upf.user_id = ?)' , [
2022-04-18 10:33:18 -07:00
$this -> data () -> id ,
]) -> results ();
2020-12-13 19:38:04 +01:00
2022-04-18 10:33:18 -07:00
$fields = [];
2021-10-08 20:45:57 +02:00
2022-04-18 10:33:18 -07:00
foreach ( $rows as $row ) {
$field = new UserProfileField ( $row );
// Check that the field is public, or they are viewing private fields
// also if they're checking forum fields, check that the field is a forum field
// TODO: ideally within the query
if (( $field -> public || $show_private ) && ( ! $only_forum || $field -> forum_posts )) {
$fields [ $row -> id ] = $field ;
2021-10-08 20:45:57 +02:00
}
2020-12-13 19:38:04 +01:00
}
2022-03-25 20:16:44 -07:00
2022-04-18 10:33:18 -07:00
return $fields ;
2020-12-13 19:38:04 +01:00
}
2021-04-12 18:36:34 -07:00
/**
* Is a user blocked ?
*
2024-03-09 03:19:55 -08:00
* @ param int $user ID of first user
2021-04-12 18:36:34 -07:00
* @ param int $blocked ID of user who may or may not be blocked
2021-10-08 20:12:07 +02:00
*
2021-04-12 18:36:34 -07:00
* @ return bool Whether they are blocked or not .
2020-12-13 19:38:04 +01:00
*/
2024-03-09 03:19:55 -08:00
public function isBlocked ( int $user , int $blocked ) : bool
{
2025-04-29 12:51:01 -07:00
return DB :: getInstance () -> query (
'SELECT 1 FROM nl2_blocked_users WHERE user_id = ? AND user_blocked_id = ?' ,
[ $user , $blocked ]
) -> exists ();
2017-08-26 15:59:37 +01:00
}
2020-12-13 19:52:09 +01:00
/**
2021-04-12 18:36:34 -07:00
* Get this user ' s profile views .
2020-12-13 19:52:09 +01:00
*
2021-04-12 18:36:34 -07:00
* @ return int Numer of profile views they have
2020-12-13 19:52:09 +01:00
*/
2024-03-09 03:19:55 -08:00
public function getProfileViews () : int
{
2022-03-10 12:32:04 -08:00
if ( $this -> exists ()) {
2020-12-13 19:38:04 +01:00
return $this -> data () -> profile_views ;
}
2021-04-12 18:36:34 -07:00
return 0 ;
2020-12-13 19:38:04 +01:00
}
2017-11-25 13:18:48 +01:00
2020-12-13 19:52:09 +01:00
/**
* Is private profile enabled and does he have the permission to use it ?
*
2021-04-12 18:36:34 -07:00
* @ return bool Whether profile privatizing is allowed and if they have permission to use it .
2020-12-13 19:52:09 +01:00
*/
2024-03-09 03:19:55 -08:00
public function canPrivateProfile () : bool
{
2023-06-12 10:30:49 -06:00
return Settings :: get ( 'private_profile' ) === '1' && $this -> hasPermission ( 'usercp.private_profile' );
2017-11-26 13:14:21 +01:00
}
2022-08-13 23:34:11 +01:00
/**
* Can the user bypass private profiles ?
*
* @ return bool Whether the user can bypass private profiles
*/
2024-03-09 03:19:55 -08:00
public function canBypassPrivateProfile () : bool
{
2023-06-12 10:30:49 -06:00
return Settings :: get ( 'private_profile' ) === '1' && $this -> hasPermission ( 'profile.private.bypass' );
2022-08-13 23:34:11 +01:00
}
2020-12-13 19:52:09 +01:00
/**
* Is the profile page set to private ?
*
2021-04-12 18:36:34 -07:00
* @ return bool Whether their profile is set to private or not .
2020-12-13 19:52:09 +01:00
*/
2024-03-09 03:19:55 -08:00
public function isPrivateProfile () : bool
{
2022-04-17 16:53:58 -07:00
return $this -> data () -> private_profile ? ? false ;
2017-11-26 13:14:21 +01:00
}
2020-12-13 19:52:09 +01:00
/**
2021-04-12 18:36:34 -07:00
* Get templates this user ' s group has access to .
2020-12-13 19:52:09 +01:00
*
2021-10-07 14:02:46 -07:00
* @ return array Templates which the user has access to .
2020-12-13 19:52:09 +01:00
*/
2024-03-09 03:19:55 -08:00
public function getUserTemplates () : array
{
2020-12-13 19:38:04 +01:00
$groups = '(' ;
2023-03-23 20:01:23 -07:00
foreach ( $this -> getGroups () as $group ) {
2022-06-02 20:45:06 +02:00
$groups .= (( int ) $group -> id ) . ',' ;
2020-12-13 19:38:04 +01:00
}
$groups = rtrim ( $groups , ',' ) . ')' ;
2023-03-23 20:01:23 -07:00
return $this -> _db -> query ( " SELECT template.id, template.name FROM nl2_templates AS template WHERE template.enabled = 1 AND template.id IN (SELECT template_id FROM nl2_groups_templates WHERE can_use_template = 1 AND group_id IN $groups ) " ) -> results ();
2020-12-13 19:38:04 +01:00
}
2021-05-14 10:35:30 -07:00
/**
2024-10-17 23:21:27 -07:00
* Save / update this user ' s placeholders .
2021-10-08 20:12:07 +02:00
*
2024-03-09 03:19:55 -08:00
* @ param int $server_id Server ID from staffcp -> integrations to assoc these placeholders with .
2021-05-14 10:35:30 -07:00
* @ param array $placeholders Key / value array of placeholders name / value from API endpoint .
*/
2024-03-09 03:19:55 -08:00
public function savePlaceholders ( int $server_id , array $placeholders ) : void
{
2022-04-16 18:42:24 +02:00
$integrationUser = $this -> getIntegration ( 'Minecraft' );
2022-07-03 20:56:15 +02:00
if ( $integrationUser === null || ! $integrationUser -> getIntegration () -> isEnabled ()) {
2022-04-16 18:42:24 +02:00
return ;
}
$uuid = hex2bin ( str_replace ( '-' , '' , $integrationUser -> data () -> identifier ));
2021-05-14 10:35:30 -07:00
foreach ( $placeholders as $name => $value ) {
Placeholders :: getInstance () -> registerPlaceholder ( $server_id , $name );
$last_updated = time ();
2022-05-01 23:16:22 -07:00
$this -> _db -> query ( 'INSERT INTO nl2_users_placeholders (server_id, uuid, name, value, last_updated) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE value = ?, last_updated = ?' , [
2021-05-14 10:35:30 -07:00
$server_id ,
2021-08-24 19:23:36 +01:00
$uuid ,
2021-05-14 10:35:30 -07:00
$name ,
$value ,
$last_updated ,
$value ,
2024-03-09 03:19:55 -08:00
$last_updated ,
2021-05-14 10:35:30 -07:00
]);
}
}
2024-03-31 20:19:43 +01:00
/**
* Get user ' s notification preferences .
*
* TODO : return type ( PHP 8 )
*
* @ param string $type Optional type of notification to filter by
*
* @ return UserNotificationData | UserNotificationData [] | null
*/
public function getNotificationPreferences ( string $type = '' )
{
if ( $this -> exists ()) {
$where = 'user_id = ?' ;
$whereVars = [ $this -> data () -> id ];
if ( ! empty ( $type )) {
$where .= ' AND `type` = ?' ;
$whereVars [] = $type ;
}
$this -> _db -> get (
<<< SQL
SELECT `type` , `alert` , `email`
FROM nl2_users_notification_preferences
WHERE $where
SQL ,
$whereVars
);
if ( ! empty ( $type )) {
return $this -> _db -> first ();
}
return $this -> _db -> results ();
}
return null ;
}
2017-03-16 19:05:52 +00:00
}