Files
streamline-emr/docker/_streamline-src/app/Http/Controllers/UserController.php
T

630 lines
24 KiB
PHP
Executable File

<?php
namespace Streamline\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use OwenIt\Auditing\Models\Audit;
use Spatie\Permission\Models\Role;
use Streamline\Enums\Roles;
use Streamline\Models\GeneralSettings;
use Streamline\Models\PasswordSecurity;
use Streamline\Models\SecurityQuestion;
use Streamline\Models\StaffPositions;
use Streamline\Models\User;
class UserController extends Controller
{
public function __construct()
{
$this->middleware('permission:users-list', ['only' => ['index']]);
$this->middleware('permission:users-create', ['only' => ['create', 'store']]);
$this->middleware('permission:users-edit', ['only' => ['edit', 'update']]);
$this->middleware('permission:users-delete', ['only' => ['destroy']]);
$this->middleware('check-active-users-limit', ['only' => ['create', 'store', 'activate']]);
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$data = User::orderBy('first_name', 'asc')->get();
$roles = Role::orderBy('name', 'asc')->select('name', 'id')->get();
$positions = StaffPositions::pluck('name', 'id');
return view('users.index', compact('data', 'positions', 'roles'))->with('i', ($request->input('page', 1) - 1) * 10);
}
public function find_users_by_role(Request $request){
$positions = StaffPositions::pluck('name', 'id');
$roles = Role::orderBy('name', 'asc')->select('name', 'id')->get();
$role = Role::where('id', $request->role)->first();
$data = User::role($role->name)->get();
return view('users.index', compact('data', 'positions', 'roles'))->with('i', ($request->input('page', 1) - 1) * 10);
}
/**
* Get online users
*/
public function onlineusers()
{
$users = User::select("*")
->whereNotNull('last_seen')
->orderBy('last_seen', 'DESC')
->paginate(25);
return view('users.online_users', compact('users'));
}
/**
* Get online users
*/
public function online_users_search(Request $request)
{
$users = User::select("*")
->whereNotNull('last_seen')
->orderBy('last_seen', 'DESC')
->paginate(25);
return view('users.online_users', compact('users'));
}
/**
* Get failed logins
*/
public function failedlogins()
{
$failed_logins = DB::table('failed_login_attempts')->select("*")
->whereNotNull('user_id')
->orderBy('created_at', 'DESC')
->where('created_at', '>=', Carbon::now()->subDay())
->paginate(100);
return view('users.failed_logins', compact('failed_logins'));
}
/**
* Search failed logins
*/
public function failed_logins_search(Request $request)
{
$failed_logins = null;
$dates = $request->dates;
$filters = [];
switch ($dates) {
case 'today':
$today = Carbon::today()->format('Y-m-d');
$failed_logins = DB::table('failed_login_attempts')->orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', $today)->paginate(100);
break;
case 'yesterday':
$yesterday = Carbon::yesterday()->format('Y-m-d');
$failed_logins = DB::table('failed_login_attempts')->orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', $yesterday)->paginate(100);
break;
case 'week':
$week_ago = Carbon::today()->subDays(7)->format('Y-m-d');
$failed_logins = DB::table('failed_login_attempts')->orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', '>=', $week_ago)->paginate(100);
break;
case 'month':
$month_ago = Carbon::today()->subDays(30)->format('Y-m-d');
$failed_logins = DB::table('failed_login_attempts')->orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', '>=', $month_ago)->paginate(100);
break;
case 'custom-date':
$start_date = Carbon::parse($request->start_date)->format('Y-m-d');
$failed_logins = DB::table('failed_login_attempts')->orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', '=', $start_date)->paginate(100);
break;
case 'custom-range':
$start_date = Carbon::parse($request->start_date)->format('Y-m-d');
$end_date = Carbon::parse($request->end_date)->format('Y-m-d');
$failed_logins = DB::table('failed_login_attempts')->orderBy('created_at', 'desc')->where($filters)->whereBetween('created_at', [$start_date, $end_date])->paginate(100);
break;
default:
$failed_logins = DB::table('failed_login_attempts')->orderBy('created_at', 'desc')->whereNotNull('user_id')->where($filters)->paginate(25);
break;
}
return view('users.failed_logins', compact('failed_logins'));
}
/**
* Search for online user records with given parameters
*
* @param Request $request
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Foundation\Application|\Illuminate\View\View
*/
public function search(Request $request)
{
$user_id = $request->user_id;
$action_performed = $request->action_performed;
$records_affected = $request->records_affected;
// Get the selected date criteria
$dates = $request->dates;
$filters = [];
if ($user_id != 'all') :
array_push($filters, ['user_id', '=', $user_id]);
endif;
if ($action_performed != 'all') :
array_push($filters, ['event', '=', $action_performed]);
endif;
if ($records_affected != 'all') :
array_push($filters, ['auditable_type', '=', 'Streamline\\' . $records_affected]);
endif;
// switch the selected date search criteria - today, yesterday, last week, last month etc
switch ($dates) {
case 'today':
$today = Carbon::today()->format('Y-m-d');
$audits = Audit::orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', $today)->paginate(100);
break;
case 'yesterday':
$yesterday = Carbon::yesterday()->format('Y-m-d');
$audits = Audit::orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', $yesterday)->paginate(100);
break;
case 'week':
$week_ago = Carbon::today()->subDays(7)->format('Y-m-d');
$audits = Audit::orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', '>=', $week_ago)->paginate(100);
break;
case 'month':
$month_ago = Carbon::today()->subDays(30)->format('Y-m-d');
$audits = Audit::orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', '>=', $month_ago)->paginate(100);
break;
case 'custom-date':
$start_date = Carbon::parse($request->start_date)->format('Y-m-d');
$audits = Audit::orderBy('created_at', 'desc')->where($filters)->whereDate('created_at', '=', $start_date)->paginate(100);
break;
case 'custom-range':
$start_date = Carbon::parse($request->start_date)->format('Y-m-d');
$end_date = Carbon::parse($request->end_date)->format('Y-m-d');
$audits = Audit::orderBy('created_at', 'desc')->where($filters)->whereBetween('created_at', [$start_date, $end_date])->paginate(100);
break;
default:
$users = User::orderBy('created_at', 'desc')->where($filters)->paginate(150);
break;
}
if ($users->count() <= 0) {
flash("There are no records found in the search")->error();
}
// users with activity
$user_id_array = DB::table('users')->groupBy('user_id')->select('user_id')->get()->toArray();
$user_id = array(count($user_id_array));
foreach ($user_id_array as $value) {
$user_id[$value->user_id] = get_full_name($value->user_id, 'id', 'first_name', 'last_name', 'users');
}
// remove the count from the array
unset($user_id[0]);
// add --select--
$user_id = ['all' => 'ALL'] + $user_id;
// users with activity
$action_performed_array = DB::table('audits')->groupBy('event')->select('event')->get()->toArray();
$action_performed = array(count($action_performed_array));
foreach ($action_performed_array as $value) {
$action_performed[$value->event] = ucwords($value->event);
}
// remove the count from the array
unset($action_performed[0]);
// add --select--
$action_performed = ['all' => 'ALL'] + $action_performed;
// users with activity
$records_affected_array = DB::table('audits')->groupBy('auditable_type')->select('auditable_type')->get()->toArray();
$records_affected = array(count($records_affected_array));
foreach ($records_affected_array as $value) {
$record = str_replace('Streamline\\', '', $value->auditable_type);
//$records_affected[$record] = $record;
/*================ show better text on forming the drop down ===========*/
$cleaned_model_name = str_replace('Streamline\\', '', $value->auditable_type);
$cleaned_model_name = preg_split('/(?=[A-Z])/', $cleaned_model_name);
$spaced_model_name = implode(' ', $cleaned_model_name);
/*========================================================*/
$records_affected[$record] = $spaced_model_name;
}
// remove the count from the array
unset($records_affected[0]);
// add --select--
$records_affected = ['all' => 'ALL'] + $records_affected;
// get all first names
$first_names = DB::table('users')->pluck('first_name', 'id');
// get all last names
$last_names = DB::table('users')->pluck('last_name', 'id');
return view('users.online_users', compact('users', 'first_names', 'last_names', 'user_id', 'action_performed', 'records_affected'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$positions = DB::table('staff_positions')->orderBy('name')->pluck('name', 'id');
$positions->prepend('- select -', '');
$councils = DB::table('licence_councils')->orderBy('name')->pluck('name', 'id');
$councils->prepend('- select -', '');
$blood_groups = DB::table('blood_groups')->orderBy('name')->pluck('name', 'id');
$blood_groups->prepend('- select -', '');
$security_questions = SecurityQuestion::orderBy('name')->pluck('name', 'id');
$security_questions->prepend('- select -', '');
if (Auth::user()->hasRole(Roles::SUPER_ADMIN->value)) {
$roles = Role::pluck('name', 'name')->all();
} else {
$roles = Role::where('name', '!=', Roles::SUPER_ADMIN->value)->pluck('name', 'name')->all();
}
return view('users.create', compact('positions', 'councils', 'blood_groups', 'roles', 'security_questions'));
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->validate($request, [
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'username' => 'required|string|max:255|unique:users',
//'email' => 'unique:users',
//'pin' => 'required|min:5|max:5',
'position_id' => 'required|integer',
'council_registration' => 'required',
'blood_group_id' => 'required|integer',
'willing_to_donate' => 'required',
'last_donation_date' => 'date_format:d/m/Y|nullable',
'expiry_date' => 'date_format:d/m/Y|nullable',
'password' => 'required|min:6|confirmed',
'photo' => 'image|mimes:jpeg,png,jpg,gif|max:2048',
]);
$user = new User();
/*
* Dealing with the photo
*/
if ($request->hasFile('photo')):
$photo = $request->file('photo');
$photo_name = str_slug($request->username) . '.' . $photo->getClientOriginalExtension();
$destinationPath = public_path('/uploads/users');
$photoPath = $destinationPath . "/" . $photo_name;
$photo->move($destinationPath, $photoPath);
$user->photo = $photo_name;
else:
$user->photo = 'placeholder.png';
endif;
$user->first_name = $request->first_name;
$user->last_name = $request->last_name;
$user->username = $request->username;
$user->phone = $request->phone;
$user->position_id = $request->position_id;
$user->council_registration = $request->council_registration;
$user->council_id = $request->council_id;
$user->registration_number = $request->registration_number;
$user->expiry_date = $request->expiry_date;
$user->email = $request->email;
//$user->pin = $request->pin;
$user->pin = "";
$user->blood_group_id = $request->blood_group_id;
$user->willing_to_donate = $request->willing_to_donate;
$user->last_donation_date = $request->last_donation_date;
$user->password = Hash::make($request->password);
$user->security_question_id = $request->security_question_id;
$user->security_answer = $request->security_answer;
$user->created_by = Auth::user()->id;
$user->save();
$this_user = User::find($user->id);
$this_user->assignRole($request->input('roles'));
// $user = User::create($input);
// $user->assignRole($request->input('roles'));
/*========= start catering for password expiration ========*/
$general_settings = GeneralSettings::find(1);
$user_password_expiration_days = $general_settings->password_expiration_days;
$passwordSecurity = PasswordSecurity::create([
'user_id' => $user->id,
'password_expiry_days' => $user_password_expiration_days,
'password_updated_at' => Carbon::now(),
]);
/*=========== end catering for password expiration =========*/
return redirect()->route('users.index')->with('success', 'New user has been registered on stre@mline');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$user = User::find($id);
$positions = DB::table('staff_positions')->pluck('name', 'id');
$councils = DB::table('licence_councils')->pluck('name', 'id');
$security_questions = SecurityQuestion::pluck('name', 'id');
$blood_groups = DB::table('blood_groups')->pluck('name', 'id');
return view('users.show', compact('user', 'positions', 'blood_groups', 'councils', 'security_questions'));
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$positions = DB::table('staff_positions')->orderBy('name')->pluck('name', 'id');
$positions->prepend('- select -', '');
$councils = DB::table('licence_councils')->orderBy('name')->pluck('name', 'id');
$councils->prepend('- select -', '');
$blood_groups = DB::table('blood_groups')->orderBy('name')->pluck('name', 'id');
$blood_groups->prepend('- select -', '');
$security_questions = SecurityQuestion::orderBy('name')->pluck('name', 'id');
$security_questions->prepend('- select -', '');
$user = User::find($id);
if (Auth::user()->hasRole(Roles::SUPER_ADMIN->value)) {
$roles = Role::pluck('name', 'name')->all();
} else {
$roles = Role::where('name', '!=', Roles::SUPER_ADMIN->value)->pluck('name', 'name')->all();
}
$userRole = $user->roles->pluck('name', 'name')->all();
return view('users.edit', compact('positions', 'councils', 'blood_groups', 'user', 'roles', 'userRole', 'security_questions'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$this->validate($request, [
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'username' => 'required|string|max:255|unique:users,username,' . $id,
//'email' => 'unique:users,email,' . $id,
//'pin' => 'required|min:5|max:5',
'position_id' => 'required|integer',
'council_registration' => 'required',
'blood_group_id' => 'required|integer',
'willing_to_donate' => 'required',
'last_donation_date' => 'date_format:d/m/Y|nullable',
'expiry_date' => 'date_format:d/m/Y|nullable',
'password' => 'min:6|confirmed|nullable',
'photo' => 'image|mimes:jpeg,png,jpg,gif|max:2048',
]);
$user = User::find($id);
/*
* Dealing with the uploaded photo
*/
if ($request->hasFile('photo')):
$photo = $request->file('photo');
$photo_name = str_slug($request->username) . '.' . $photo->getClientOriginalExtension();
$destinationPath = public_path('/uploads/users');
$photoPath = $destinationPath . "/" . $photo_name;
$photo->move($destinationPath, $photoPath);
$user->photo = $photo_name;
endif;
// check if a password has been inserted
if ($request->password) {
$user->password = Hash::make($request->password);
}
$user->first_name = $request->first_name;
$user->last_name = $request->last_name;
$user->username = $request->username;
$user->phone = $request->phone;
$user->position_id = $request->position_id;
$user->council_registration = $request->council_registration;
$user->council_id = $request->council_id;
$user->registration_number = $request->registration_number;
$user->expiry_date = $request->expiry_date;
$user->email = $request->email;
$user->pin = $request->pin;
$user->blood_group_id = $request->blood_group_id;
$user->willing_to_donate = $request->willing_to_donate;
$user->last_donation_date = $request->last_donation_date;
$user->security_question_id = $request->security_question_id;
$user->security_answer = $request->security_answer;
$user->updated_by = Auth::user()->id;
$user->save();
if (Auth::user()->can('edit-users-role')):
DB::table('model_has_roles')->where('model_id', $id)->delete();
$this_user = User::find($id);
$this_user->assignRole($request->input('roles'));
endif;
return redirect()->route('users.index')->with('success', 'The user has been updated successfully');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
// check if user to be deleted is the same one logged in
if (Auth::user()->id == $id) {
flash("You cannot delete a user who is logged in.")->error();
return redirect('/users/');
}
$user = User::find($id);
if ($user->delete()):
flash("User has been deleted.")->success();
return redirect('/users/');
endif;
}
/**
* Display a listing of the inactive resource(s).
*
* @return \Illuminate\Http\Response
*/
public function inactive()
{
$users = User::onlyTrashed()
->orderBy('email', 'asc')
->paginate(50);
if (count($users) < 1) {
flash()->error("There is no inactive user");
return redirect('/users/');
} else {
return view('users.inactive', compact('users'));
}
}
/**
* Activate the specified resource in storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function activate($id)
{
$user = User::withTrashed()->find($id);
if ($user->restore()):
flash("User has been activated.")->success();
return redirect('/users/inactive');
endif;
}
public function check_reset(Request $request)
{
$question_id = $request->security_question_id;
$answer = $request->security_answer;
$pin = $request->pin;
/*
* Check if the combination of email and PIN exists in the database
*/
$user = User::where([
['security_question_id', '=', $question_id],
['security_answer', '=', $answer],
['pin', '=', $pin],
])->first();
if ($user === null):
// user doesn't exist, combination is wrongo
flash('Security question, answer or PIN is incorrect. Please verify and try again.')->error();
return redirect()->route('login');
else:
$full_name = $user->first_name . " " . $user->last_name;
$id = $user->id;
$username = $user->username;
flash('Security question, answer and PIN match! Please reset your password below.')->info();
return view('users.reset', compact('full_name', 'username', 'id'));
endif;
}
public function reset_password(Request $request)
{
// $this->validate($request, [
// 'password' => 'min:6|confirmed',
// ]);
$user = User::find($request->id);
$user->password = Hash::make($request->password);
$user->save();
flash('Success! Please login with your new password.')->success();
return redirect()->route('login');
}
public function search_user_by_name(Request $request)
{
$data = [];
if ($request->has('q')) {
$search = $request->q;
$data = User::select("id", "first_name", "last_name")
->orWhere('first_name', 'LIKE', "%$search%")
->orWhere('last_name', 'LIKE', "%$search%")
->get();
}
return response()->json($data);
}
}