Add manual subreddit/YouTube channel configuration (manage.php)
Browser-based feed selection layered on top of config/feeds.php: - manage.php (password + CSRF gated, session based): add subreddits (name / r/name / URL) and YouTube channels (@handle / UC id / URL, handle resolved to channel_id once, youtube.com only); enable/disable toggles; remove manual feeds; config feeds are hidden, not deleted. - New feeds are validated with one immediate fetch (bypassing the per-refresh host cap): HTTP 404 rejects the entry, 429 keeps it for a later refresh. YouTube labels adopt the real channel title. - feeds table gains origin (config|manual) and enabled columns, with a guarded ALTER migration for existing databases. - Only enabled feeds are refreshed and served: getItems/countItems filter by feed_url in enabled feeds, so deselected feeds' cached stories are hidden, not deleted; re-adding a URL re-enables it. - Dashboard header gets a Manage link; manage page styled with the existing design tokens; README documents the feature.
This commit is contained in:
+71
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Manual feed configuration: sign in, then add/remove/toggle subreddits and
|
||||
* YouTube channels. POST actions redirect (PRG); results surface as flash.
|
||||
*/
|
||||
|
||||
/** @var array<string, mixed> $app */
|
||||
$app = require __DIR__ . '/src/bootstrap.php';
|
||||
|
||||
$config = $app['config'];
|
||||
$manager = $app['manager'];
|
||||
$service = $app['service'];
|
||||
|
||||
$auth = new App\ManageAuth($config);
|
||||
|
||||
$redirect = static function (): never {
|
||||
header('Location: manage.php', true, 303);
|
||||
exit;
|
||||
};
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$token = is_string($_POST['csrf'] ?? null) ? $_POST['csrf'] : '';
|
||||
$action = is_string($_POST['action'] ?? null) ? $_POST['action'] : '';
|
||||
$input = is_string($_POST['input'] ?? null) ? trim($_POST['input']) : '';
|
||||
$url = is_string($_POST['url'] ?? null) ? trim($_POST['url']) : '';
|
||||
$enabled = is_string($_POST['enabled'] ?? null) && $_POST['enabled'] === '1';
|
||||
|
||||
if (!$auth->enabled() || !$auth->checkCsrf($token)) {
|
||||
$auth->flash('err', 'Session expired — please try again.');
|
||||
$redirect();
|
||||
}
|
||||
|
||||
if ($action === 'logout') {
|
||||
$auth->logout();
|
||||
$auth->flash('ok', 'Signed out.');
|
||||
$redirect();
|
||||
}
|
||||
|
||||
if ($action === 'login') {
|
||||
if (!$auth->login($input)) {
|
||||
$auth->flash('err', 'Wrong password.');
|
||||
}
|
||||
$redirect();
|
||||
}
|
||||
|
||||
$result = $auth->authed() ? match ($action) {
|
||||
'add_reddit' => $manager->addReddit($input),
|
||||
'add_youtube' => $manager->addYouTube($input),
|
||||
'toggle' => $manager->setEnabled($url, $enabled),
|
||||
'remove' => $manager->remove($url),
|
||||
default => null,
|
||||
} : null;
|
||||
|
||||
if ($result === null) {
|
||||
$auth->flash('err', 'Please sign in first.');
|
||||
} else {
|
||||
$auth->flash($result['ok'] ? 'ok' : 'err', $result['message']);
|
||||
}
|
||||
|
||||
$redirect();
|
||||
}
|
||||
|
||||
echo App\View::render('manage', [
|
||||
'config' => $config,
|
||||
'auth' => $auth,
|
||||
'feeds' => $auth->authed() ? $service->feedsStatus() : [],
|
||||
'flash' => $auth->takeFlash(),
|
||||
]);
|
||||
Reference in New Issue
Block a user