snipe-it/app/Http/Controllers/Users/BulkUsersController.php
Daniel Meltzer 64d649be7f Monster: Cleanup/Refactor http controllers. (#5916)
* Extract a handlesimages trait to centralize logic for parsing/storing images on upload in create/edit methods.

* Use same image upload/layout in accessories as consum+components.

* Monster: Cleanup/Refactor http controllers.

This cleans up docblocks, pulls most non-crudy actions into their own
controllers, and does general cleanup/logic refactoring.  There /should/
be no functional changes, but we all know how should works..

Extract checkin/checkout functions to a separate controller for accessories.

Move controllers to subdirectory.

Cleanup AssetModelsController

Extract component checkin/checkout

Assorted cleanups/doc/formatting in controllers.

Refactor LicenseController.

Refactor UsersController

Update viewassetscontroller.

* Codacy cleanups

* More codacy cleanups.  Extract a LicenseCheckout Form request as well.

* A bit more refactor/cleaning of the license checkout method.

* Review Related Cleanups

* Fix most of the item_not_found translations.  In many cases, the
string being generated did not even use the id parameter.  Where it
does, pass it as id instead of as a different value.

* Remove some old $data arrays from when we manually sent emails from
the controllers.  This has been superseeded by the notification system
(yay!)

* Bugfix: Only log the checkin of an accessory if the checkin completes sucessfully.
2018-07-24 19:35:26 -07:00

205 lines
6.9 KiB
PHP

<?php
namespace App\Http\Controllers\Users;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Models\Accessory;
use App\Models\Actionlog;
use App\Models\Asset;
use App\Models\Group;
use App\Models\LicenseSeat;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class BulkUsersController extends Controller
{
/**
* Returns a view that confirms the user's a bulk delete will be applied to.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.7]
* @param Request $request
* @return \Illuminate\Contracts\View\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function edit(Request $request)
{
$this->authorize('update', User::class);
if (($request->has('ids')) && (count($request->input('ids')) > 0)) {
$statuslabel_list = Helper::statusLabelList();
$users = User::whereIn('id', array_keys(request('ids')))
->with('groups', 'assets', 'licenses', 'accessories')->get();
if ($request->input('bulk_actions') == 'edit') {
return view('users/bulk-edit', compact('users'))
->with('groups', Group::pluck('name', 'id'));
}
return view('users/confirm-bulk-delete', compact('users', 'statuslabel_list'));
}
return redirect()->back()->with('error', 'No users selected');
}
/**
* Save bulk-edited users
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(Request $request)
{
$this->authorize('update', User::class);
if((!$request->has('ids')) || $request->input('ids') <= 0) {
return redirect()->back()->with('error', 'No users selected');
}
$user_raw_array = $request->input('ids');
// Remove the user from any updates.
$user_raw_array = array_diff($user_raw_array, [Auth::id()]);
$manager_conflict = false;
$users = User::whereIn('id', $user_raw_array)->where('id', '!=', Auth::user()->id)->get();
$return_array = [
'success' => trans('admin/users/message.success.update_bulk')
];
$this->conditionallyAddItem('location_id')
->conditionallyAddItem('department_id')
->conditionallyAddItem('company_id')
->conditionallyAddItem('locale')
->conditionallyAddItem('activated')
;
// If the manager_id is one of the users being updated, generate a warning.
if (array_search($request->input('manager_id'), $user_raw_array)) {
$manager_conflict = true;
$return_array = [
'warning' => trans('admin/users/message.bulk_manager_warn')
];
}
if (!$manager_conflict) {
$this->conditionallyAddItem('manager_id');
}
// Save the updated info
User::whereIn('id', $user_raw_array)
->where('id', '!=', Auth::id())->update($this->update_array);
// Only sync groups if groups were selected
if ($request->has('groups')) {
foreach ($users as $user) {
$user->groups()->sync($request->input('groups'));
}
}
return redirect()->route('users.index')
->with($return_array);
}
/**
* Array to store update data per item
* @var Array
*/
private $update_array = [];
/**
* Adds parameter to update array for an item if it exists in request
* @param String $field field name
* @return BulkUsersController Model for Chaining
*/
protected function conditionallyAddItem($field)
{
if(request()->has($field)) {
$this->update_array[$field] = request()->input($field);
}
return $this;
}
/**
* Soft-delete bulk users
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function destroy(Request $request)
{
$this->authorize('update', User::class);
if ((!$request->has('ids')) || (count($request->input('ids')) == 0)) {
return redirect()->back()->with('error', 'No users selected');
}
if ((!$request->has('status_id')) || ($request->input('status_id')=='')) {
return redirect()->route('users.index')->with('error', 'No status selected');
}
if (config('app.lock_passwords')) {
return redirect()->route('users.index')->with('error', 'Bulk delete is not enabled in this installation');
}
$user_raw_array = request('ids');
if (($key = array_search(Auth::id(), $user_raw_array)) !== false) {
unset($user_raw_array[$key]);
}
$users = User::whereIn('id', $user_raw_array)->get();
$assets = Asset::whereIn('assigned_to', $user_raw_array)->get();
$accessories = DB::table('accessories_users')->whereIn('assigned_to', $user_raw_array)->get();
$licenses = DB::table('license_seats')->whereIn('assigned_to', $user_raw_array)->get();
$this->logItemCheckinAndDelete($assets, Asset::class);
$this->logItemCheckinAndDelete($accessories, Accessory::class);
$this->logItemCheckinAndDelete($licenses, LicenseSeat::class);
Asset::whereIn('id', $assets->pluck('id'))->update([
'status_id' => e(request('status_id')),
'assigned_to' => null,
'assigned_type' => null,
]);
LicenseSeat::whereIn('id', $licenses->pluck('id'))->update(['assigned_to' => null]);
foreach ($users as $user) {
$user->accessories()->sync([]);
$user->delete();
}
return redirect()->route('users.index')->with('success', 'Your selected users have been deleted and their assets have been updated.');
}
/**
* Generate an action log entry for each of a group of items.
* @param $items
* @param $itemType string name of items being passed.
*/
protected function logItemCheckinAndDelete($items, $itemType) {
foreach($items as $item) {
$logAction = new Actionlog();
$logAction->item_id = $item->id;
// We can't rely on get_class here because the licenses/accessories fetched above are not eloquent models, but simply arrays.
$logAction->item_type = $itemType;
$logAction->target_id = $item->assigned_to;
$logAction->target_type = User::class;
$logAction->user_id = Auth::id();
$logAction->note = 'Bulk checkin items and delete user';
$logAction->logaction('checkin from');
}
}
}