snipe-it/app/Http/Controllers/Api/LocationsController.php

340 lines
12 KiB
PHP
Raw Normal View History

2017-01-12 19:40:20 -08:00
<?php
namespace App\Http\Controllers\Api;
use App\Helpers\Helper;
2021-06-29 02:28:42 -07:00
use App\Http\Requests\ImageUploadRequest;
2017-01-12 19:40:20 -08:00
use App\Http\Controllers\Controller;
use App\Http\Transformers\AssetsTransformer;
use App\Http\Transformers\LocationsTransformer;
use App\Http\Transformers\SelectlistTransformer;
use App\Models\Asset;
use App\Models\Location;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Illuminate\Http\JsonResponse;
2017-01-12 19:40:20 -08:00
class LocationsController extends Controller
{
/**
* Display a listing of the resource.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return \Illuminate\Http\Response
*/
public function index(Request $request) : JsonResponse | array
2017-01-12 19:40:20 -08:00
{
$this->authorize('view', Location::class);
$allowed_columns = [
'id',
'name',
'address',
'address2',
'city',
'state',
'country',
'zip',
'created_at',
'updated_at',
'manager_id',
'image',
'assigned_assets_count',
'users_count',
'assets_count',
'assigned_assets_count',
'assets_count',
'rtd_assets_count',
'currency',
'ldap_ou',
];
$locations = Location::with('parent', 'manager', 'children')->select([
'locations.id',
'locations.name',
'locations.address',
'locations.address2',
'locations.city',
'locations.state',
'locations.zip',
'locations.phone',
'locations.fax',
'locations.country',
'locations.parent_id',
'locations.manager_id',
2017-03-10 22:09:21 -08:00
'locations.created_at',
'locations.updated_at',
'locations.image',
'locations.ldap_ou',
'locations.currency',
])->withCount('assignedAssets as assigned_assets_count')
->withCount('assets as assets_count')
->withCount('rtd_assets as rtd_assets_count')
->withCount('children as children_count')
->withCount('users as users_count');
2019-05-23 17:39:50 -07:00
if ($request->filled('search')) {
$locations = $locations->TextSearch($request->input('search'));
}
if ($request->filled('name')) {
$locations->where('locations.name', '=', $request->input('name'));
}
if ($request->filled('address')) {
$locations->where('locations.address', '=', $request->input('address'));
}
if ($request->filled('address2')) {
$locations->where('locations.address2', '=', $request->input('address2'));
}
if ($request->filled('city')) {
$locations->where('locations.city', '=', $request->input('city'));
}
if ($request->filled('zip')) {
$locations->where('locations.zip', '=', $request->input('zip'));
}
if ($request->filled('country')) {
$locations->where('locations.country', '=', $request->input('country'));
}
if ($request->filled('manager_id')) {
$locations->where('locations.manager_id', '=', $request->input('manager_id'));
}
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $locations->count()) ? $locations->count() : app('api_offset_value');
$limit = app('api_limit_value');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
2018-02-21 02:17:18 -08:00
2018-02-21 02:17:18 -08:00
switch ($request->input('sort')) {
case 'parent':
$locations->OrderParent($order);
break;
2018-02-21 05:09:40 -08:00
case 'manager':
$locations->OrderManager($order);
break;
2018-02-21 02:17:18 -08:00
default:
$locations->orderBy($sort, $order);
break;
}
$total = $locations->count();
$locations = $locations->skip($offset)->take($limit)->get();
return (new LocationsTransformer)->transformLocations($locations, $total);
2017-01-12 19:40:20 -08:00
}
/**
* Store a newly created resource in storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
2021-06-29 02:28:42 -07:00
* @param \App\Http\Requests\ImageUploadRequest $request
2017-01-12 19:40:20 -08:00
*/
public function store(ImageUploadRequest $request) : JsonResponse
2017-01-12 19:40:20 -08:00
{
$this->authorize('create', Location::class);
$location = new Location;
$location->fill($request->all());
2021-06-29 02:28:42 -07:00
$location = $request->handleImages($location);
2017-01-12 19:40:20 -08:00
if ($location->save()) {
return response()->json(Helper::formatStandardApiResponse('success', (new LocationsTransformer)->transformLocation($location), trans('admin/locations/message.create.success')));
2017-01-12 19:40:20 -08:00
}
2017-01-12 19:40:20 -08:00
return response()->json(Helper::formatStandardApiResponse('error', null, $location->getErrors()));
}
/**
* Display the specified resource.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
*/
public function show($id) : JsonResponse | array
2017-01-12 19:40:20 -08:00
{
$this->authorize('view', Location::class);
$location = Location::with('parent', 'manager', 'children')
->select([
'locations.id',
'locations.name',
'locations.address',
'locations.address2',
'locations.city',
'locations.state',
'locations.zip',
'locations.country',
'locations.parent_id',
'locations.manager_id',
'locations.created_at',
'locations.updated_at',
'locations.image',
'locations.currency',
])
->withCount('assignedAssets as assigned_assets_count')
->withCount('assets as assets_count')
->withCount('rtd_assets as rtd_assets_count')
->withCount('users as users_count')
->findOrFail($id);
return (new LocationsTransformer)->transformLocation($location);
2017-01-12 19:40:20 -08:00
}
/**
* Update the specified resource in storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
2021-06-29 02:28:42 -07:00
* @param \App\Http\Requests\ImageUploadRequest $request
2017-01-12 19:40:20 -08:00
* @param int $id
*/
public function update(ImageUploadRequest $request, $id) : JsonResponse
2017-01-12 19:40:20 -08:00
{
$this->authorize('update', Location::class);
2017-01-12 19:40:20 -08:00
$location = Location::findOrFail($id);
2017-01-12 19:40:20 -08:00
$location->fill($request->all());
2021-06-29 02:28:42 -07:00
$location = $request->handleImages($location);
if ($location->isValid()) {
$location->save();
return response()->json(
Helper::formatStandardApiResponse(
'success',
(new LocationsTransformer)->transformLocation($location),
trans('admin/locations/message.update.success')
)
);
2017-01-12 19:40:20 -08:00
}
return response()->json(Helper::formatStandardApiResponse('error', null, $location->getErrors()));
}
public function assets(Request $request, Location $location) : JsonResponse | array
{
$this->authorize('view', Asset::class);
$this->authorize('view', $location);
$assets = Asset::where('assigned_to', '=', $location->id)->where('assigned_type', '=', Location::class)->with('model', 'model.category', 'assetstatus', 'location', 'company', 'defaultLoc');
$assets = $assets->get();
return (new AssetsTransformer)->transformAssets($assets, $assets->count(), $request);
}
2017-01-12 19:40:20 -08:00
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
*/
public function destroy($id) : JsonResponse
2017-01-12 19:40:20 -08:00
{
$this->authorize('delete', Location::class);
2024-03-19 15:25:28 -07:00
$location = Location::withCount('assignedAssets as assigned_assets_count')
->withCount('assets as assets_count')
->withCount('rtd_assets as rtd_assets_count')
->withCount('children as children_count')
->withCount('users as users_count')
->withCount('accessories as accessories_count')
2024-03-19 15:25:28 -07:00
->findOrFail($id);
if (! $location->isDeletable()) {
return response()
->json(Helper::formatStandardApiResponse('error', null, trans('admin/locations/message.assoc_users')));
}
2017-01-12 19:40:20 -08:00
$this->authorize('delete', $location);
$location->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/locations/message.delete.success')));
2017-01-12 19:40:20 -08:00
}
/**
* Gets a paginated collection for the select2 menus
*
* This is handled slightly differently as of ~4.7.8-pre, as
* we have to do some recursive magic to get the hierarchy to display
* properly when looking at the parent/child relationship in the
* rich menus.
*
* This means we can't use the normal pagination that we use elsewhere
* in our selectlists, since we have to get the full set before we can
* determine which location is parent/child/grandchild, etc.
*
* This also means that hierarchy display gets a little funky when people
* use the Select2 search functionality, but there's not much we can do about
* that right now.
*
* As a result, instead of paginating as part of the query, we have to grab
* the entire data set, and then invoke a paginator manually and pass that
* through to the SelectListTransformer.
*
* Many thanks to @uberbrady for the help getting this working better.
* Recursion still sucks, but I guess he doesn't have to get in the
* sea... this time.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0.16]
* @see \App\Http\Transformers\SelectlistTransformer
*/
public function selectlist(Request $request) : array
{
// If a user is in the process of editing their profile, as determined by the referrer,
// then we check that they have permission to edit their own location.
// Otherwise, we do our normal check that they can view select lists.
$request->headers->get('referer') === route('profile')
? $this->authorize('self.edit_location')
: $this->authorize('view.selectlists');
$locations = Location::select([
'locations.id',
'locations.name',
'locations.parent_id',
'locations.image',
]);
$page = 1;
if ($request->filled('page')) {
$page = $request->input('page');
}
if ($request->filled('search')) {
$locations = $locations->where('locations.name', 'LIKE', '%'.$request->input('search').'%');
}
$locations = $locations->orderBy('name', 'ASC')->get();
$locations_with_children = [];
foreach ($locations as $location) {
if (! array_key_exists($location->parent_id, $locations_with_children)) {
$locations_with_children[$location->parent_id] = [];
}
$locations_with_children[$location->parent_id][] = $location;
}
if ($request->filled('search')) {
$locations_formatted = $locations;
} else {
$location_options = Location::indenter($locations_with_children);
$locations_formatted = new Collection($location_options);
}
$paginated_results = new LengthAwarePaginator($locations_formatted->forPage($page, 500), $locations_formatted->count(), 500, $page, []);
return (new SelectlistTransformer)->transformSelectlist($paginated_results);
}
}