diff --git a/src/Http/Controllers/Character/IntelController.php b/src/Http/Controllers/Character/IntelController.php index 0ec2c1361..ba8c3197c 100644 --- a/src/Http/Controllers/Character/IntelController.php +++ b/src/Http/Controllers/Character/IntelController.php @@ -32,6 +32,7 @@ use Seat\Eveapi\Models\Wallet\CharacterWalletTransaction; use Seat\Web\Http\Controllers\Controller; use Seat\Web\Http\DataTables\Character\Intel\NoteDataTable; +use Seat\Web\Http\DataTables\Scopes\CharacterNoteScope; use Seat\Web\Models\StandingsProfile; use Seat\Web\Models\User; use Yajra\DataTables\DataTables; @@ -282,6 +283,8 @@ public function getCompareStandingsWithProfileData(CharacterInfo $character, int */ public function notes(CharacterInfo $character, NoteDataTable $dataTable) { + $dataTable->addScope(new CharacterNoteScope([$character->character_id])); + return $dataTable->render('web::character.intel.notes', compact('character')); } diff --git a/src/Http/DataTables/Scopes/CharacterNoteScope.php b/src/Http/DataTables/Scopes/CharacterNoteScope.php new file mode 100644 index 000000000..b235a9ba4 --- /dev/null +++ b/src/Http/DataTables/Scopes/CharacterNoteScope.php @@ -0,0 +1,134 @@ +requested_characters = $character_id; + } + + /** + * Apply a query scope. + * + * @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query + * @return mixed + */ + public function apply($query) + { + if ($this->requested_characters != null) { + $character_ids = collect($this->requested_characters)->filter(function ($item) { + return Gate::allows('character.intel', [$item]); + }); + + return $character_ids->count() == count($this->requested_characters) ? + $query->whereIn('object_id', $this->requested_characters) : + $query->whereIn('object_id', []); + } + + if (auth()->user()->isAdmin()) + return $query; + + // collect metadata related to required permission + $permissions = auth()->user()->roles()->with('permissions')->get() + ->pluck('permissions') + ->flatten() + ->filter(function ($permission) { + return $permission->title == 'character.intel'; + }); + + // in case at least one permission is granted without restrictions, return all + if ($permissions->filter(function ($permission) { return ! $permission->hasFilters(); })->isNotEmpty()) + return $query; + + // extract entity ids and group by entity type + $map = $permissions->map(function ($permission) { + $filters = json_decode($permission->pivot->filters); + + return [ + 'characters' => collect($filters->character ?? [])->pluck('id')->toArray(), + 'corporations' => collect($filters->corporation ?? [])->pluck('id')->toArray(), + 'alliances' => collect($filters->alliance ?? [])->pluck('id')->toArray(), + ]; + }); + + // collect at least user owned characters + $owned_range = auth()->user()->associatedCharacterIds(); + + $characters_range = $map->pluck('characters')->flatten()->toArray(); + + $corporations_range = CharacterInfo::whereHas('affiliation', function ($affiliation) use ($map) { + $affiliation->whereIn('corporation_id', $map->pluck('corporations')->flatten()->toArray()); + })->select('character_id')->get()->pluck('character_id')->toArray(); + + $alliances_range = CharacterInfo::whereHas('affiliation', function ($affiliation) use ($map) { + $affiliation->whereIn('alliance_id', $map->pluck('alliances')->flatten()->toArray()); + })->select('character_id')->get()->pluck('character_id')->toArray(); + + // sharelink + $sharelink = session()->get('user_sharing') ?: []; + + $associated_ceo_corporations = CorporationInfo::whereIn('ceo_id', $owned_range)->get(); + $ceo_range = []; + foreach ($associated_ceo_corporations as $corporation) { + $ceo_range += $corporation->characters->pluck('character_id')->values()->toArray(); + } + + $associated_corporations = auth()->user()->characters->load('affiliation')->pluck('affiliation.corporation_id')->values()->toArray(); + $director_roles_corporations = CorporationRole::whereIn('corporation_id', $associated_corporations)->whereIn('character_id', $owned_range) + ->where('role', 'Director')->where('type', 'roles') + ->pluck('corporation_id')->values()->toArray(); + $director_corporations = CorporationInfo::with('characters')->whereIn('corporation_id', $director_roles_corporations)->get(); + $director_range = []; + foreach ($director_corporations as $corporation) { + $director_range += $corporation->characters->pluck('character_id')->values()->toArray(); + } + + // merge all collected characters IDs in a single array and apply filter + $character_ids = array_merge($characters_range, $corporations_range, $alliances_range, $owned_range, $sharelink, $ceo_range, $director_range); + + return $query->whereIn('object_id', $character_ids); + } +}