134 lines
3.7 KiB
PHP
134 lines
3.7 KiB
PHP
<?php
|
||
|
||
namespace App\Services;
|
||
|
||
use Illuminate\Support\Collection;
|
||
use Illuminate\Support\Facades\Auth;
|
||
use App\Models\City;
|
||
use App\Models\Management;
|
||
|
||
/**
|
||
* メニュー・アクセス制御サービス
|
||
*
|
||
* ログイン中のオペレータが属する運営元に基づいて、
|
||
* 表示可能なメニュー項目およびアクセス可能な画面を制御します。
|
||
* ソーリンは全メニュー/全画面OK、その他は所属自治体のみアクセス可。
|
||
*/
|
||
class MenuAccessService
|
||
{
|
||
/**
|
||
* ログイン中のオペレータを取得
|
||
*/
|
||
private function getAuthOperator()
|
||
{
|
||
return Auth::user();
|
||
}
|
||
|
||
/**
|
||
* ログイン中のオペレータが属する運営元を取得
|
||
*/
|
||
private function getAuthManagement(): ?Management
|
||
{
|
||
$operator = $this->getAuthOperator();
|
||
if (!$operator || !isset($operator->management_id)) {
|
||
return null;
|
||
}
|
||
|
||
return Management::find($operator->management_id);
|
||
}
|
||
|
||
/**
|
||
* ログイン中のオペレータがソーリンであるか判定
|
||
*
|
||
* ソーリン(management_name === 'ソーリン')の場合は全メニュー表示可能
|
||
*
|
||
* @return bool true: ソーリン, false: その他
|
||
*/
|
||
public function isSorin(): bool
|
||
{
|
||
$management = $this->getAuthManagement();
|
||
if (!$management) {
|
||
return false;
|
||
}
|
||
|
||
return $management->management_name === 'ソーリン';
|
||
}
|
||
|
||
/**
|
||
* オペレータが表示可能な自治体リストを取得
|
||
*
|
||
* ソーリン: 全自治体(削除フラグなどは既存仕様に合わせる)
|
||
* その他: ope.city_id で指定された1つの自治体のみ
|
||
*
|
||
* @return Collection<City>
|
||
*/
|
||
public function visibleCities(): Collection
|
||
{
|
||
if ($this->isSorin()) {
|
||
return City::query()
|
||
->orderBy('city_name')
|
||
->get();
|
||
}
|
||
|
||
// 非ソーリン時は ope.city_id で指定された自治体のみ
|
||
$operator = $this->getAuthOperator();
|
||
if (!$operator || !isset($operator->city_id)) {
|
||
return collect();
|
||
}
|
||
|
||
// ope.city_id に一致する city のみを返す
|
||
$city = City::find($operator->city_id);
|
||
if (!$city) {
|
||
return collect();
|
||
}
|
||
|
||
return collect([$city]);
|
||
}
|
||
|
||
/**
|
||
* 指定された自治体へのアクセスが許可されているか判定
|
||
*
|
||
* ソーリン: 常に true
|
||
* その他: city.management_id == ope.management_id の場合のみ true
|
||
*
|
||
* @param int $cityId 自治体ID
|
||
* @return bool true: アクセス許可, false: アクセス拒否
|
||
*/
|
||
public function canAccessCity(int $cityId): bool
|
||
{
|
||
if ($this->isSorin()) {
|
||
return true;
|
||
}
|
||
|
||
$operator = $this->getAuthOperator();
|
||
if (!$operator || !isset($operator->management_id)) {
|
||
return false;
|
||
}
|
||
|
||
// city.management_id が ope.management_id と一致するか確認
|
||
$city = City::find($cityId);
|
||
if (!$city) {
|
||
return false;
|
||
}
|
||
|
||
return (int)$city->management_id === (int)$operator->management_id;
|
||
}
|
||
|
||
/**
|
||
* 複数の自治体へのアクセス許可を一括確認
|
||
*
|
||
* @param array<int> $cityIds 自治体IDの配列
|
||
* @return bool すべての自治体へのアクセスが許可されている場合のみ true
|
||
*/
|
||
public function canAccessCities(array $cityIds): bool
|
||
{
|
||
foreach ($cityIds as $cityId) {
|
||
if (!$this->canAccessCity($cityId)) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
}
|