fedi-feed-router/backend/app/Http/Controllers/RoutingController.php

174 lines
5.1 KiB
PHP
Raw Normal View History

2025-07-05 18:26:04 +02:00
<?php
namespace App\Http\Controllers;
use App\Models\Feed;
2025-07-10 11:14:06 +02:00
use App\Models\Route;
2025-07-05 18:26:04 +02:00
use App\Models\PlatformChannel;
use App\Services\RoutingValidationService;
use App\Exceptions\RoutingMismatchException;
2025-07-07 02:48:46 +02:00
use Illuminate\Database\Eloquent\Collection;
2025-07-05 18:26:04 +02:00
use Illuminate\Http\Request;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
class RoutingController extends Controller
{
public function index(): View
{
$feeds = Feed::with(['channels.platformInstance'])
->where('is_active', true)
->orderBy('name')
->get();
$channels = PlatformChannel::with(['platformInstance', 'feeds'])
->where('is_active', true)
->orderBy('name')
->get();
return view('pages.routing.index', compact('feeds', 'channels'));
}
public function create(): View
{
$feeds = Feed::where('is_active', true)
->orderBy('name')
->get();
$channels = PlatformChannel::with('platformInstance')
->where('is_active', true)
->orderBy('name')
->get();
return view('pages.routing.create', compact('feeds', 'channels'));
}
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'feed_id' => 'required|exists:feeds,id',
'channel_ids' => 'required|array|min:1',
'channel_ids.*' => 'exists:platform_channels,id',
'priority' => 'integer|min:0|max:100',
'filters' => 'nullable|string'
]);
2025-07-07 02:48:46 +02:00
/** @var Feed $feed */
2025-07-05 18:26:04 +02:00
$feed = Feed::findOrFail($validated['feed_id']);
2025-07-07 02:48:46 +02:00
/** @var Collection<int, PlatformChannel> $channels */
2025-07-05 18:26:04 +02:00
$channels = PlatformChannel::findMany($validated['channel_ids']);
$priority = $validated['priority'] ?? 0;
try {
app(RoutingValidationService::class)->validateLanguageCompatibility($feed, $channels);
} catch (RoutingMismatchException $e) {
return redirect()->back()
->withInput()
->withErrors(['language' => $e->getMessage()]);
}
$filters = $this->parseJsonFilters($validated['filters'] ?? null);
// Attach channels to feed
$syncData = [];
foreach ($validated['channel_ids'] as $channelId) {
$syncData[$channelId] = [
'is_active' => true,
'priority' => $priority,
'filters' => $filters,
'created_at' => now(),
'updated_at' => now()
];
}
$feed->channels()->syncWithoutDetaching($syncData);
return redirect()->route('routing.index')
->with('success', 'Feed routing created successfully!');
}
public function edit(Feed $feed, PlatformChannel $channel): View
{
$routing = $feed->channels()
->wherePivot('platform_channel_id', $channel->id)
->first();
if (! $routing) {
abort(404, 'Routing not found');
}
return view('pages.routing.edit', compact('feed', 'channel', 'routing'));
}
public function update(Request $request, Feed $feed, PlatformChannel $channel): RedirectResponse
{
$validated = $request->validate([
'is_active' => 'boolean',
'priority' => 'integer|min:0|max:100',
'filters' => 'nullable|string'
]);
$filters = $this->parseJsonFilters($validated['filters'] ?? null);
$feed->channels()->updateExistingPivot($channel->id, [
'is_active' => $validated['is_active'] ?? true,
'priority' => $validated['priority'] ?? 0,
'filters' => $filters,
'updated_at' => now()
]);
return redirect()->route('routing.index')
->with('success', 'Routing updated successfully!');
}
public function destroy(Feed $feed, PlatformChannel $channel): RedirectResponse
{
$feed->channels()->detach($channel->id);
return redirect()->route('routing.index')
->with('success', 'Routing deleted successfully!');
}
public function toggle(Request $request, Feed $feed, PlatformChannel $channel): RedirectResponse
{
2025-07-10 11:14:06 +02:00
$routing = Route::where('feed_id', $feed->id)
2025-07-06 20:37:55 +02:00
->where('platform_channel_id', $channel->id)
2025-07-05 18:26:04 +02:00
->first();
if (! $routing) {
abort(404, 'Routing not found');
}
2025-07-06 20:37:55 +02:00
$newStatus = ! $routing->is_active;
2025-07-05 18:26:04 +02:00
$feed->channels()->updateExistingPivot($channel->id, [
'is_active' => $newStatus,
'updated_at' => now()
]);
$status = $newStatus ? 'activated' : 'deactivated';
return redirect()->route('routing.index')
->with('success', "Routing {$status} successfully!");
}
2025-07-07 00:51:32 +02:00
/**
* @return array<string, mixed>|null
*/
2025-07-05 18:26:04 +02:00
private function parseJsonFilters(?string $json): ?array
{
if (empty($json)) {
return null;
}
$decoded = json_decode($json, true);
if (json_last_error() === JSON_ERROR_NONE) {
return $decoded;
}
return null;
}
}