1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2019 webtrees development team 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16declare(strict_types=1); 17 18namespace Fisharebest\Webtrees\Services; 19 20use Fisharebest\Webtrees\Auth; 21use Fisharebest\Webtrees\Individual; 22use Fisharebest\Webtrees\User; 23use Illuminate\Database\Capsule\Manager as DB; 24use Illuminate\Database\Query\JoinClause; 25use Illuminate\Support\Collection; 26 27/** 28 * Functions for managing users. 29 */ 30class UserService 31{ 32 /** 33 * Find the user with a specified user_id. 34 * 35 * @param int|null $user_id 36 * 37 * @return User|null 38 */ 39 public function find($user_id) 40 { 41 return app('cache.array')->rememberForever(__CLASS__ . $user_id, function () use ($user_id) { 42 return DB::table('user') 43 ->where('user_id', '=', $user_id) 44 ->get() 45 ->map(User::rowMapper()) 46 ->first(); 47 }); 48 } 49 50 /** 51 * Find the user with a specified email address. 52 * 53 * @param string $email 54 * 55 * @return User|null 56 */ 57 public function findByEmail($email) 58 { 59 return DB::table('user') 60 ->where('email', '=', $email) 61 ->get() 62 ->map(User::rowMapper()) 63 ->first(); 64 } 65 66 /** 67 * Find the user with a specified user_name or email address. 68 * 69 * @param string $identifier 70 * 71 * @return User|null 72 */ 73 public function findByIdentifier($identifier) 74 { 75 return DB::table('user') 76 ->where('user_name', '=', $identifier) 77 ->orWhere('email', '=', $identifier) 78 ->get() 79 ->map(User::rowMapper()) 80 ->first(); 81 } 82 83 /** 84 * Find the user(s) with a specified genealogy record. 85 * 86 * @param Individual $individual 87 * 88 * @return Collection|User[] 89 */ 90 public function findByIndividual(Individual $individual): Collection 91 { 92 return DB::table('user') 93 ->join('user_gedcom_setting', 'user_gedcom_setting.user_id', '=', 'user.user_id') 94 ->where('gedcom_id', '=', $individual->tree()->id()) 95 ->where('setting_value', '=', $individual->xref()) 96 ->where('setting_name', '=', 'gedcomid') 97 ->select(['user.*']) 98 ->get() 99 ->map(User::rowMapper()); 100 } 101 102 /** 103 * Find the user with a specified user_name. 104 * 105 * @param string $user_name 106 * 107 * @return User|null 108 */ 109 public function findByUserName($user_name) 110 { 111 return DB::table('user') 112 ->where('user_name', '=', $user_name) 113 ->get() 114 ->map(User::rowMapper()) 115 ->first(); 116 } 117 118 /** 119 * Get a list of all users. 120 * 121 * @return Collection|User[] 122 */ 123 public function all(): Collection 124 { 125 return DB::table('user') 126 ->where('user_id', '>', 0) 127 ->orderBy('real_name') 128 ->get() 129 ->map(User::rowMapper()); 130 } 131 132 /** 133 * Get a list of all administrators. 134 * 135 * @return Collection|User[] 136 */ 137 public function administrators(): Collection 138 { 139 return DB::table('user') 140 ->join('user_setting', function (JoinClause $join): void { 141 $join 142 ->on('user_setting.user_id', '=', 'user.user_id') 143 ->where('user_setting.setting_name', '=', 'canadmin') 144 ->where('user_setting.setting_value', '=', '1'); 145 }) 146 ->where('user.user_id', '>', 0) 147 ->orderBy('real_name') 148 ->select(['user.*']) 149 ->get() 150 ->map(User::rowMapper()); 151 } 152 153 /** 154 * Get a list of all managers. 155 * 156 * @return Collection|User[] 157 */ 158 public function managers(): Collection 159 { 160 return DB::table('user') 161 ->join('user_gedcom_setting', function (JoinClause $join): void { 162 $join 163 ->on('user_gedcom_setting.user_id', '=', 'user.user_id') 164 ->where('user_gedcom_setting.setting_name', '=', 'canedit') 165 ->where('user_gedcom_setting.setting_value', '=', 'admin'); 166 }) 167 ->where('user.user_id', '>', 0) 168 ->orderBy('real_name') 169 ->select(['user.*']) 170 ->get() 171 ->map(User::rowMapper()); 172 } 173 174 /** 175 * Get a list of all moderators. 176 * 177 * @return Collection|User[] 178 */ 179 public function moderators(): Collection 180 { 181 return DB::table('user') 182 ->join('user_gedcom_setting', function (JoinClause $join): void { 183 $join 184 ->on('user_gedcom_setting.user_id', '=', 'user.user_id') 185 ->where('user_gedcom_setting.setting_name', '=', 'canedit') 186 ->where('user_gedcom_setting.setting_value', '=', 'accept'); 187 }) 188 ->where('user.user_id', '>', 0) 189 ->orderBy('real_name') 190 ->select(['user.*']) 191 ->get() 192 ->map(User::rowMapper()); 193 } 194 195 /** 196 * Get a list of all verified users. 197 * 198 * @return Collection|User[] 199 */ 200 public function unapproved(): Collection 201 { 202 return DB::table('user') 203 ->join('user_setting', function (JoinClause $join): void { 204 $join 205 ->on('user_setting.user_id', '=', 'user.user_id') 206 ->where('user_setting.setting_name', '=', 'verified_by_admin') 207 ->where('user_setting.setting_value', '=', '0'); 208 }) 209 ->where('user.user_id', '>', 0) 210 ->orderBy('real_name') 211 ->select(['user.*']) 212 ->get() 213 ->map(User::rowMapper()); 214 } 215 216 /** 217 * Get a list of all verified users. 218 * 219 * @return Collection|User[] 220 */ 221 public function unverified(): Collection 222 { 223 return DB::table('user') 224 ->join('user_setting', function (JoinClause $join): void { 225 $join 226 ->on('user_setting.user_id', '=', 'user.user_id') 227 ->where('user_setting.setting_name', '=', 'verified') 228 ->where('user_setting.setting_value', '=', '0'); 229 }) 230 ->where('user.user_id', '>', 0) 231 ->orderBy('real_name') 232 ->select(['user.*']) 233 ->get() 234 ->map(User::rowMapper()); 235 } 236 237 /** 238 * Get a list of all users who are currently logged in. 239 * 240 * @return Collection|User[] 241 */ 242 public function allLoggedIn(): Collection 243 { 244 return DB::table('user') 245 ->join('session', 'session.user_id', '=', 'user.user_id') 246 ->where('user.user_id', '>', 0) 247 ->orderBy('real_name') 248 ->select(['user.*']) 249 ->distinct() 250 ->get() 251 ->map(User::rowMapper()); 252 } 253 254 /** 255 * Create a new user. 256 * The calling code needs to check for duplicates identifiers before calling 257 * this function. 258 * 259 * @param string $user_name 260 * @param string $real_name 261 * @param string $email 262 * @param string $password 263 * 264 * @return User 265 */ 266 public static function create(string $user_name, string $real_name, string $email, string $password): User 267 { 268 DB::table('user')->insert([ 269 'user_name' => $user_name, 270 'real_name' => $real_name, 271 'email' => $email, 272 'password' => password_hash($password, PASSWORD_DEFAULT), 273 ]); 274 275 $user_id = (int) DB::connection()->getPdo()->lastInsertId(); 276 277 return new User($user_id, $user_name, $real_name, $email); 278 } 279 280 /** 281 * Delete a user 282 * 283 * @param User $user 284 * 285 * @return void 286 */ 287 public function delete(User $user) 288 { 289 // Don't delete the logs, just set the user to null. 290 DB::table('log') 291 ->where('user_id', '=', $user->id()) 292 ->update(['user_id' => null]); 293 294 // Take over the user’s pending changes. (What else could we do with them?) 295 DB::table('change') 296 ->where('user_id', '=', $user->id()) 297 ->where('status', '=', 'rejected') 298 ->delete(); 299 300 DB::table('change') 301 ->where('user_id', '=', $user->id()) 302 ->update(['user_id' => Auth::id()]); 303 304 // Delete settings and preferences 305 DB::table('block_setting') 306 ->join('block', 'block_setting.block_id', '=', 'block.block_id') 307 ->where('user_id', '=', $user->id()) 308 ->delete(); 309 310 DB::table('block')->where('user_id', '=', $user->id())->delete(); 311 DB::table('user_gedcom_setting')->where('user_id', '=', $user->id())->delete(); 312 DB::table('user_setting')->where('user_id', '=', $user->id())->delete(); 313 DB::table('message')->where('user_id', '=', $user->id())->delete(); 314 DB::table('user')->where('user_id', '=', $user->id())->delete(); 315 } 316} 317