You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

195 lines
5.7 KiB

  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Models\User;
  4. use App\Models\Business;
  5. use Illuminate\Http\Request;
  6. use Illuminate\Support\Facades\Auth;
  7. use Illuminate\Support\Facades\DB;
  8. class BusinessController extends Controller
  9. {
  10. public function index()
  11. {
  12. return auth()->user()->businesses
  13. ->keyBy('id')
  14. ->map(fn($b, $bid) => Business::info($bid));
  15. }
  16. public function store(Request $request)
  17. {
  18. // $users = [];
  19. // foreach ($request->users ?? [] as $key => $value) {
  20. // $users[$value] = [];
  21. // }
  22. // $owner = [
  23. // Auth::id() => [
  24. // 'level' => enum('levels.owner.id'),
  25. // ]
  26. // ];
  27. //
  28. // $users = $users + $owner;
  29. //
  30. // $request->merge(['users' => $users]);
  31. $business = Business::create($request->all());
  32. $business->users()->sync([Auth::id() => [
  33. 'level' => enum('levels.owner.id'),
  34. ]
  35. ], false);
  36. return Business::info($business->id);
  37. }
  38. public function show(string $business)
  39. {
  40. permit('businessAccess');
  41. return Business::info($business);
  42. }
  43. public function update(Request $request, string $business)
  44. {
  45. // permit('businessEdit');
  46. $business = Business::findOrFail($business);
  47. $business->fill($request->all())->save();
  48. return Business::info($business->id);
  49. }
  50. public function setAvatar(Request $request, string $business)
  51. {
  52. $business = Business::findOrFail($business);
  53. if ($request->hasFile('avatar')) {
  54. $business->saveAsAvatar($request->file('avatar'));
  55. }
  56. return Business::info($business->id);
  57. }
  58. public function unSetAvatar(Request $request, string $business)
  59. {
  60. $business = Business::findOrFail($business);
  61. $business->deleteAvatar();
  62. return Business::info($business->id);
  63. }
  64. public function info(string $business)
  65. {
  66. return request('_business_info');
  67. }
  68. public function restore(string $business)
  69. {
  70. $business = Business::onlyTrashed()->findOrFail($business);
  71. $business->restore();
  72. return response(['message' => 'business successfully restored.']);
  73. }
  74. public function storeOrUpdateUser($business, Request $request)
  75. {
  76. permit('businessUsers');
  77. $validatedData = $this->validate($request, [
  78. 'level' => 'required|numeric|between:0,4',
  79. 'user_id' => 'required|numeric|not_in:'.auth()->id(),
  80. ]);
  81. DB::transaction(function () use ($validatedData, $request, $business) {
  82. $this->addUser($business, $request->user_id, $validatedData);
  83. if (can('businessAccess', ['user_id'=> $request->user_id])) {
  84. //update
  85. $this->relatedUpdateChanges($request->user_id, $request->level);
  86. }
  87. }, 3);
  88. return Business::info($business, true);
  89. }
  90. public function relatedUpdateChanges($user_id, $level)
  91. {
  92. if ($level == enum('levels.owner.id')) {
  93. // user up level to owner
  94. $this->removeProjectDirectRelation($user_id);
  95. }
  96. if ($level != enum('levels.owner.id') &&
  97. $level > request('_business_info')['info']['users'][$user_id]['level']) {
  98. // user at least up level to $request->level
  99. $this->updateProjectAccessLevel($level, $user_id);
  100. }
  101. }
  102. public function addUser($business, $user, $validatedData)
  103. {
  104. $businessModel = Business::findOrFail($business);
  105. $businessModel->users()->sync([$user => $validatedData], false);
  106. }
  107. public function removeProjectDirectRelation($user)
  108. {
  109. $userModel = User::findOrFail($user);
  110. return $userModel->projects()->sync([], true);
  111. }
  112. public function updateProjectAccessLevel($level, $user)
  113. {
  114. $ids = [];
  115. foreach (request('_business_info')['projects'] as $project_id => $item) {
  116. foreach ($item['members'] as $idx => $member) {
  117. if ($member['id'] == $user && $member['level'] != enum('levels.inactive.id') && $member['level'] < $level) {
  118. $ids[$project_id] = ['level' => $level];
  119. break;
  120. }
  121. }
  122. }
  123. $userModel = User::findOrFail($user);
  124. return $userModel->projects()->sync($ids, false);
  125. }
  126. public function deleteUser($business, $user)
  127. {
  128. permit('businessAccess');
  129. $this->checkDeleteUserPolicy($user);
  130. $businessModel = Business::findOrFail($business);
  131. DB::transaction(function () use ($user, $businessModel) {
  132. $this->detachUser($businessModel, $user);
  133. $this->removeProjectDirectRelation($user);
  134. }, 3);
  135. return Business::info($business, true);
  136. }
  137. public function haveAnotherOwner($user)
  138. {
  139. foreach (request('_business_info')['info']['users'] as $id => $item) {
  140. if ($item['level'] == enum('levels.owner.id') && $id != $user) {
  141. return true;
  142. }
  143. }
  144. return false;
  145. }
  146. public function detachUser($business, $user)
  147. {
  148. return $business->users()->sync(
  149. $business->users->except($user)->pluck('id')->toArray()
  150. );
  151. }
  152. public function checkDeleteUserPolicy($user)
  153. {
  154. if (!can('isBusinessOwner') && auth()->id() != $user ) {
  155. // Non owner user remove another owner
  156. abort(405);
  157. }
  158. if (can('isBusinessOwner') && auth()->id() == $user && !$this->haveAnotherOwner($user)) {
  159. // Owner remove self but business haven't another owner
  160. abort(405);
  161. }
  162. }
  163. }