66use Illuminate \Database \Eloquent \Factories \HasFactory ;
77use Illuminate \Foundation \Auth \User as Authenticatable ;
88use Illuminate \Notifications \Notifiable ;
9+ use Illuminate \Support \Str ;
910use Spatie \Permission \Traits \HasRoles ;
1011
1112class User extends Authenticatable
@@ -20,6 +21,7 @@ class User extends Authenticatable
2021 protected $ fillable = [
2122 'name ' ,
2223 'email ' ,
24+ 'username ' ,
2325 'password ' ,
2426 ];
2527
@@ -41,4 +43,60 @@ class User extends Authenticatable
4143 protected $ casts = [
4244 'email_verified_at ' => 'datetime ' ,
4345 ];
46+
47+ public static function boot ()
48+ {
49+ parent ::boot ();
50+
51+ static ::saving (function ($ model ) {
52+ $ model ->setUsername ();
53+ });
54+ }
55+
56+ protected function usernameExists (string $ username ): bool
57+ {
58+ return self ::where ('username ' , $ username )->exists ();
59+ }
60+
61+ public function setUsername (): void
62+ {
63+ // Early return if username is already set
64+ if ($ this ->username ) {
65+ return ;
66+ }
67+
68+ $ baseUsername = $ this ->generateBaseUsername ();
69+ $ this ->username = $ this ->generateUniqueUsername ($ baseUsername );
70+ }
71+
72+ private function generateBaseUsername (): string
73+ {
74+ return Str::of ($ this ->name )
75+ ->ascii ()
76+ ->lower ()
77+ ->replaceMatches ('/[\s._-]+/ ' , '' ) // Replace multiple special characters at once
78+ ->trim ();
79+ }
80+
81+ private function generateUniqueUsername (string $ baseUsername ): string
82+ {
83+ $ username = $ baseUsername ;
84+
85+ // If base username is already unique, return it
86+ if (! $ this ->usernameExists ($ username )) {
87+ return $ username ;
88+ }
89+
90+ // Generate a random suffix between 100000 and 999999
91+ $ suffix = random_int (100000 , 999999 );
92+ $ username = $ baseUsername .$ suffix ;
93+
94+ // In the unlikely case of collision, increment until unique
95+ while ($ this ->usernameExists ($ username )) {
96+ $ suffix ++;
97+ $ username = $ baseUsername .$ suffix ;
98+ }
99+
100+ return $ username ;
101+ }
44102}
0 commit comments