- Applied `Confirmation` trait to multiple Livewire components for unified confirmation handling. - Replaced inline confirmation modals with `requireConfirmation` method for streamlined interaction. - Updated button styles and added reusable confirmation prompts for delete/detach actions. - Enhanced `AppRoleService` and `ConnectionProviderService` to support deletion with confirmation.
128 lines
4.0 KiB
PHP
128 lines
4.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Data\ConnectedApp\{ConnectionProviderData, StoreConnectionProviderRequestData};
|
|
use App\Models\ConnectionProvider;
|
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\DB;
|
|
use InvalidArgumentException;
|
|
use NoDiscard;
|
|
use Spatie\LaravelData\PaginatedDataCollection;
|
|
use Throwable;
|
|
|
|
class ConnectionProviderService
|
|
{
|
|
public function __construct(
|
|
private readonly AppRoleService $appRoleService,
|
|
) {}
|
|
|
|
/**
|
|
* @return Collection<int, ConnectionProvider>
|
|
*/
|
|
#[NoDiscard]
|
|
public function search(string $value): Collection
|
|
{
|
|
return ConnectionProvider::query()
|
|
->whereLike('slug', "%{$value}%")
|
|
->orWhereLike('name', "%{$value}%")
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* @throws Throwable
|
|
*/
|
|
public function create(StoreConnectionProviderRequestData $data): void
|
|
{
|
|
DB::transaction(
|
|
function () use ($data): void {
|
|
ConnectionProvider::query()->create($data->toArray());
|
|
}
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @return PaginatedDataCollection<int, ConnectionProviderData>
|
|
*/
|
|
#[NoDiscard]
|
|
public function getAll(): PaginatedDataCollection
|
|
{
|
|
$data = ConnectionProvider::query()->select(['id', 'name', 'slug'])->paginate();
|
|
|
|
return ConnectionProviderData::collect($data, PaginatedDataCollection::class);
|
|
}
|
|
|
|
/**
|
|
* @throws InvalidArgumentException when id is invalid
|
|
* @throws Throwable when an error occurs during the update.
|
|
*/
|
|
public function update(string $slug, StoreConnectionProviderRequestData $data): void
|
|
{
|
|
DB::transaction(
|
|
function () use ($slug, $data): void {
|
|
$app = ConnectionProvider::query()
|
|
->where('slug', $slug);
|
|
|
|
$app->update($data->toArray());
|
|
}
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Delete the connection provider and associated connected apps.
|
|
*
|
|
* @throws ModelNotFoundException when the connection provider is not found.
|
|
* @throws Throwable when an error occurs during the deletion.
|
|
*/
|
|
public function delete(string $slug): void
|
|
{
|
|
DB::transaction(
|
|
function () use ($slug): void {
|
|
$provider = ConnectionProvider::query()
|
|
->where('slug', $slug)
|
|
->firstOrFail();
|
|
$deletedApps = $provider->connectedApps()
|
|
->select(['id', 'name'])
|
|
->get()
|
|
->toArray();
|
|
|
|
$this->appRoleService->detachApps(array_column($deletedApps, 'id'));
|
|
// Note: This performs a mass soft-delete query.
|
|
// Model events for ConnectedApp will NOT fire.
|
|
$provider->connectedApps()->delete();
|
|
// Stop the default logging
|
|
$provider->disableLogging()->delete();
|
|
|
|
activity()
|
|
->performedOn($provider)
|
|
->event('provider_cascade_deleted')
|
|
->withProperties([
|
|
'slug' => $slug,
|
|
'name' => $provider->name,
|
|
'deleted_apps_count' => count($deletedApps),
|
|
'deleted_apps' => $deletedApps,
|
|
])
|
|
->log(":causer.name Deleted connection provider '{$provider->name}' alongside ".count($deletedApps).' connected apps.');
|
|
}
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @throws ModelNotFoundException<ConnectionProviderData> when the connected app is not found.
|
|
* @throws InvalidArgumentException when id is invalid.
|
|
*/
|
|
#[NoDiscard]
|
|
public function getProvider(string $slug): ConnectionProviderData
|
|
{
|
|
$data = ConnectionProvider::query()
|
|
->select(['id', 'name', 'slug'])
|
|
->where('slug', $slug)
|
|
->first();
|
|
|
|
return ConnectionProviderData::from($data);
|
|
}
|
|
}
|