user()->businesses ->keyBy('id') ->map(fn($b, $bid) => Business::info($bid)); } public function store(Request $request) { // $users = []; // foreach ($request->users ?? [] as $key => $value) { // $users[$value] = []; // } // $owner = [ // Auth::id() => [ // 'level' => enum('levels.owner.id'), // ] // ]; // // $users = $users + $owner; // // $request->merge(['users' => $users]); $business = Business::create($request->all()); $business->users()->sync([Auth::id() => [ 'level' => enum('levels.owner.id'), ] ], false); return Business::info($business->id); } public function show(string $business) { permit('businessAccess'); return Business::info($business); } public function update(Request $request, string $business) { // permit('businessEdit'); $business = Business::findOrFail($business); $business->fill($request->all())->save(); return Business::info($business->id); } public function setAvatar(Request $request, string $business) { $business = Business::findOrFail($business); if ($request->hasFile('avatar')) { $business->saveAsAvatar($request->file('avatar')); } return Business::info($business->id); } public function unSetAvatar(Request $request, string $business) { $business = Business::findOrFail($business); $business->deleteAvatar(); return Business::info($business->id); } public function info(string $business) { return request('_business_info'); } public function restore(string $business) { $business = Business::onlyTrashed()->findOrFail($business); $business->restore(); return response(['message' => 'business successfully restored.']); } public function storeOrUpdateUser($business, Request $request) { permit('businessUsers'); $validatedData = $this->validate($request, [ 'level' => 'required|numeric|between:0,4', 'user_id' => 'required|numeric|not_in:'.auth()->id(), ]); DB::transaction(function () use ($validatedData, $request, $business) { $this->addUser($business, $request->user_id, $validatedData); if (can('businessAccess', ['user_id'=> $request->user_id])) { //update $this->relatedUpdateChanges($request->user_id, $request->level); } }, 3); return Business::info($business, true); } public function relatedUpdateChanges($user_id, $level) { if ($level == enum('levels.owner.id')) { // user up level to owner $this->removeProjectDirectRelation($user_id); } if ($level != enum('levels.owner.id') && $level > request('_business_info')['info']['users'][$user_id]['level']) { // user at least up level to $request->level $this->updateProjectAccessLevel($level, $user_id); } } public function addUser($business, $user, $validatedData) { $businessModel = Business::findOrFail($business); $businessModel->users()->sync([$user => $validatedData], false); } public function removeProjectDirectRelation($user) { $userModel = User::findOrFail($user); return $userModel->projects()->sync([], true); } public function updateProjectAccessLevel($level, $user) { $ids = []; foreach (request('_business_info')['projects'] as $project_id => $item) { foreach ($item['members'] as $idx => $member) { if ($member['id'] == $user && $member['level'] != enum('levels.inactive.id') && $member['level'] < $level) { $ids[$project_id] = ['level' => $level]; break; } } } $userModel = User::findOrFail($user); return $userModel->projects()->sync($ids, false); } public function deleteUser($business, $user) { permit('businessAccess'); $this->checkDeleteUserPolicy($user); $businessModel = Business::findOrFail($business); DB::transaction(function () use ($user, $businessModel) { $this->detachUser($businessModel, $user); $this->removeProjectDirectRelation($user); }, 3); return Business::info($business, true); } public function haveAnotherOwner($user) { foreach (request('_business_info')['info']['users'] as $id => $item) { if ($item['level'] == enum('levels.owner.id') && $id != $user) { return true; } } return false; } public function detachUser($business, $user) { return $business->users()->sync( $business->users->except($user)->pluck('id')->toArray() ); } public function checkDeleteUserPolicy($user) { if (!can('isBusinessOwner') && auth()->id() != $user ) { // Non owner user remove another owner abort(405); } if (can('isBusinessOwner') && auth()->id() == $user && !$this->haveAnotherOwner($user)) { // Owner remove self but business haven't another owner abort(405); } } }