Skip to content
This repository has been archived by the owner on Apr 29, 2022. It is now read-only.

Commit

Permalink
Merge pull request #57 from coordinape/feature/dev-343-bulk-createupd…
Browse files Browse the repository at this point in the history
…ate-user-list-api-endpoint

Bulk Api user actions
  • Loading branch information
levity authored Nov 12, 2021
2 parents f26fca8 + 44f9767 commit 9a8ca77
Show file tree
Hide file tree
Showing 10 changed files with 1,158 additions and 520 deletions.
32 changes: 28 additions & 4 deletions app/Http/Controllers/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@

use App\Http\Requests\AdminCreateUserRequest;
use App\Http\Requests\AdminUserRequest;
use App\Http\Requests\BulkUserCreateRequest;
use App\Http\Requests\BulkUserDeleteRequest;
use App\Http\Requests\BulkUserRestoreRequest;
use App\Http\Requests\BulkUserUpdateRequest;
use App\Http\Requests\UserRequest;
use App\Models\Profile;
use App\Repositories\EpochRepository;
use App\Repositories\UserRepository;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Repositories\UserRepository;
use Illuminate\Validation\ValidationException;
use App\Repositories\EpochRepository;

class UserController extends Controller
{
Expand Down Expand Up @@ -52,6 +55,7 @@ public function adminUpdateUser(AdminUserRequest $request, $circle_id, $address)
if (!$user)
return response()->json(['message' => 'Address not found'], 422);


if ($user->is_coordinape_user)
return response()->json(['message' => 'This user is not modifiable'], 422);

Expand All @@ -67,7 +71,7 @@ public function adminUpdateUser(AdminUserRequest $request, $circle_id, $address)
$data['give_token_remaining'] = $data['starting_tokens'];
}
}
$data['address'] = strtolower($data['address']);
$data['address'] = strtolower($data['address']);
$user = $this->repo->updateUserData($user, $data);
return response()->json($user);
}
Expand All @@ -88,4 +92,24 @@ public function deleteUser(Request $request, $circle_id, $address): JsonResponse
return response()->json($data);
}
}

public function bulkCreate(BulkUserCreateRequest $request): JsonResponse
{
return response()->json($this->repo->bulkCreate($request));
}

public function bulkUpdate(BulkUserUpdateRequest $request): JsonResponse
{
return response()->json($this->repo->bulkUpdate($request));
}

public function bulkDelete(BulkUserDeleteRequest $request): JsonResponse
{
return response()->json(['success' => $this->repo->bulkDelete($request)]);
}

public function bulkRestore(BulkUserRestoreRequest $request): JsonResponse
{
return response()->json([$this->repo->bulkRestore($request)]);
}
}
4 changes: 2 additions & 2 deletions app/Http/Requests/AdminCreateUserRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ public function rules()
$circle_id = $this->circle_id;
return [
'name' => 'required|string|max:255',
'address' => ['required', 'string', 'size:42', Rule::unique('users')->where(function ($query) use ($circle_id) {
return $query->where('circle_id', $circle_id)->whereNull('deleted_at');
'address' => ['required', 'string', 'size:42', Rule::unique('users')->withoutTrashed()->where(function ($query) use ($circle_id) {
return $query->where('circle_id', $circle_id);
})],
'non_giver' => 'integer|min:0|max:1|required',
'fixed_non_receiver' => 'integer|min:0|max:1|required',
Expand Down
4 changes: 2 additions & 2 deletions app/Http/Requests/AdminUserRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ public function rules()
$circle_id = $this->circle_id;
return [
'name' => 'required|string|max:255',
'address' => ['required', 'string', 'size:42',Rule::unique('users')->ignore($this->user->id)->where(function ($query) use ($circle_id) {
return $query->where('circle_id', $circle_id)->whereNull('deleted_at');
'address' => ['required', 'string', 'size:42',Rule::unique('users')->withoutTrashed()->ignore($this->user->id)->where(function ($query) use ($circle_id) {
return $query->where('circle_id', $circle_id);
})],
'starting_tokens' => 'integer|max:1000000',
'non_giver' => 'integer|min:0|max:1|required',
Expand Down
72 changes: 72 additions & 0 deletions app/Http/Requests/BulkUserCreateRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class BulkUserCreateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}

/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$circle_id = $this->route('circle_id');

return [
'users' => ['required', 'array', 'min:1'],
'users.*.address' => ['required', 'string', 'size:42', 'distinct',
// validate id is unique within circle
Rule::unique('users')->withoutTrashed()->where(function ($query) use ($circle_id) {
return $query->where('circle_id', $circle_id);
})],
'users.*.name' => ['required', 'string', 'max:255'],
'users.*.non_giver' => 'integer|min:0|max:1|nullable',
'users.*.fixed_non_receiver' => 'integer|min:0|max:1|nullable',
'users.*.starting_tokens' => 'integer|max:1000000|nullable',
'users.*.role' => 'integer|min:0|max:1|nullable'
];
}

protected function prepareForValidation()
{
$this->merge($this->sanitizeInput());

}

private function sanitizeInput(): array
{
$users = $this->get('users');
$address_array = [];
if ($users) {
$circle_id = $this->route('circle_id');
$allowed_fields = ['address', 'name', 'non_giver', 'fixed_non_receiver', 'starting_tokens', 'role'];
foreach ($users as $idx => $user) {
$users[$idx] = array_filter($user, function ($key) use ($allowed_fields) {
return in_array($key, $allowed_fields);
}
, ARRAY_FILTER_USE_KEY);
$users[$idx]['circle_id'] = $circle_id;
if (!empty($user['address'])) {
$lcAddress = strtolower($user['address']);
$users[$idx]['address'] = $lcAddress;
$address_array[] = $lcAddress;
}
}
}
return compact('users', 'address_array');
}
}
37 changes: 37 additions & 0 deletions app/Http/Requests/BulkUserDeleteRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class BulkUserDeleteRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}

/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$circle_id = $this->route('circle_id');
return [
"users" => ['required', 'array', 'min:1'],
'users.*' => ['required', 'integer', 'distinct',
//validate id exists as a user in the circle
Rule::exists('users', 'id')->withoutTrashed()->where(function ($query) use ($circle_id) {
return $query->where('circle_id', $circle_id);
})],
];
}
}
53 changes: 53 additions & 0 deletions app/Http/Requests/BulkUserRestoreRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace App\Http\Requests;

use App\Models\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class BulkUserRestoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}

/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$circle_id = $this->route('circle_id');
return [
"users" => ['required', 'array', 'min:1'],
'users.*' => ['required', 'integer', 'distinct',
//validate id exists as a deleted user in circle
Rule::exists('users', 'id')->where(function ($query) use ($circle_id) {
return $query->where('circle_id', $circle_id)->whereNotNull('deleted_at');
})],
'addresses.*' => ['distinct', 'string', 'size:42',
//validate restored user doesn't conflict with existing user addresses
Rule::unique('users', 'address')->withoutTrashed()->where(function ($query) use ($circle_id) {
return $query->where('circle_id', $circle_id);
})],
];
}

protected function prepareForValidation()
{
$users = $this->get('users');
$restoring_addresses = [];
if ($users && is_array($users)) {
$restoring_addresses = User::onlyTrashed()->whereIn('id', $users)->where('circle_id', $this->route('circle_id'))->pluck('address')->toArray();
}
$this->merge(['addresses' => $restoring_addresses]);
}
}
93 changes: 93 additions & 0 deletions app/Http/Requests/BulkUserUpdateRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace App\Http\Requests;

use App\Models\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class BulkUserUpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}

/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$user_id = $this->input('users.*.id');
$circle_id = $this->route('circle_id');
return [
'users' => ['required', 'array', 'min:1'],
'users.*.id' => ['required', 'integer',
// validate id exists as a user in circle
Rule::exists('users')->withoutTrashed()->where(function ($query) use ($circle_id) {
return $query->where('circle_id', $circle_id);
})],
'users.*.address' => ['required', 'string', 'size:42', 'distinct',
// validate address is unique within circle
Rule::unique('users')->withoutTrashed()->where(function ($query) use ($circle_id, $user_id) {
return $query->where('circle_id', $circle_id)->whereNotIn('id', $user_id);
})],
'users.*.name' => ['required', 'string', 'max:255'],
'users.*.non_giver' => 'integer|min:0|max:1|nullable',
'users.*.fixed_non_receiver' => 'integer|min:0|max:1',
'users.*.starting_tokens' => 'integer|min:0|max:1000000',
'users.*.role' => 'integer|min:0|max:1|nullable'
];
}

protected function prepareForValidation()
{
$this->merge($this->sanitizeInput());
}

private function sanitizeInput(): array
{
$users_values = $this->get('users');
$admin_user_id = $this->get('admin_user')->id;
$address_array = [];
$id_array = [];
$users = [];
if ($users_values) {
$circle_id = $this->route('circle_id');
$allowed_fields = ['id', 'address', 'name', 'non_giver', 'fixed_non_receiver', 'starting_tokens', 'role'];
$id_array = array_map(function ($u) {
return !empty($u['id']) ? $u['id'] : -1;
}, $users_values);
$users_current_data = User::where('circle_id', $circle_id)->whereIn('id', $id_array)->get()->keyBy('id');
foreach ($users_values as $users_value) {
$user_id = !empty($users_value['id']) ? $users_value['id'] : null;
if ($user_id) {
$user = [];
if ($users_current_data->has($user_id)) {
foreach ($allowed_fields as $allowed_field) {
$user[$allowed_field] = !empty($users_value[$allowed_field]) ? $users_value[$allowed_field] : $users_current_data[$user_id]->{$allowed_field};
}
$user['address'] = strtolower($user['address']);
$address_array[] = $user['address'];
if ($user_id == $admin_user_id) {
// prevents admin user from removing his own admin role
$user['role'] = config('enums.user_types.admin');
}
} else {
$user['id'] = $user_id;
}
$user['circle_id'] = $circle_id;
$users[] = $user;
}
}
}
return compact('users', 'address_array', 'id_array');
}
}
Loading

0 comments on commit 9a8ca77

Please sign in to comment.