6 changed files with 123 additions and 34 deletions
@ -0,0 +1,117 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace App\Controller\Admin; |
||||||
|
|
||||||
|
use App\Service\RSS\RssFeedService; |
||||||
|
use App\Service\RSS\RssToNostrConverter; |
||||||
|
use App\Util\NostrKeyUtil; |
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; |
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextType; |
||||||
|
use Symfony\Component\HttpFoundation\Request; |
||||||
|
use Symfony\Component\HttpFoundation\Response; |
||||||
|
use Symfony\Component\Routing\Annotation\Route; |
||||||
|
use Doctrine\ORM\EntityManagerInterface; |
||||||
|
use App\Entity\Event; |
||||||
|
use App\Enum\KindsEnum; |
||||||
|
|
||||||
|
class AdminRssController extends AbstractController |
||||||
|
{ |
||||||
|
#[Route('/admin/rss/submit', name: 'admin_rss_submit', methods: ['GET', 'POST'])] |
||||||
|
public function submitRssFeed(Request $request, RssFeedService $rssFeedService, EntityManagerInterface $entityManager): Response |
||||||
|
{ |
||||||
|
// Fetch magazines (Event entities) with type=magazine and owned by the user |
||||||
|
$user = $this->getUser(); |
||||||
|
if (!$user) { |
||||||
|
throw $this->createAccessDeniedException('You must be logged in to access this page.'); |
||||||
|
} |
||||||
|
|
||||||
|
$pubkey = NostrKeyUtil::npubToHex($user->getUserIdentifier()); |
||||||
|
|
||||||
|
$magazines = $entityManager->getRepository(Event::class)->findBy([ |
||||||
|
'kind' => KindsEnum::PUBLICATION_INDEX, |
||||||
|
'pubkey' => $pubkey, |
||||||
|
]); |
||||||
|
$filteredMagazines = array_filter($magazines, function ($mag) { |
||||||
|
$tags = $mag->getTags(); |
||||||
|
$isMagType = false; |
||||||
|
$isTopLevel = false; |
||||||
|
$hasSource = false; |
||||||
|
foreach ($tags as $tag) { |
||||||
|
if ($tag[0] === 'type' && $tag[1] === 'magazine') { |
||||||
|
$isMagType = true; |
||||||
|
} |
||||||
|
if ($tag[0] === 'a' && $isTopLevel === false) { |
||||||
|
$parts = explode(':', $tag[1]); |
||||||
|
if ($parts[0] == (string)KindsEnum::PUBLICATION_INDEX->value) { |
||||||
|
$isTopLevel = true; |
||||||
|
} |
||||||
|
} |
||||||
|
if ($tag[0] === 'source' && !empty($tag[1])) { |
||||||
|
$hasSource = true; |
||||||
|
} |
||||||
|
} |
||||||
|
// Optionally, filter by user ownership if needed |
||||||
|
return $isMagType && $isTopLevel && $hasSource; |
||||||
|
}); |
||||||
|
|
||||||
|
$form = $this->createFormBuilder() |
||||||
|
->add('feedUrl', TextType::class, [ |
||||||
|
'label' => 'RSS Feed URL', |
||||||
|
'required' => true, |
||||||
|
]) |
||||||
|
->add('magazine', TextType::class, [ |
||||||
|
'label' => 'Magazine (optional)', |
||||||
|
'required' => false, |
||||||
|
]) |
||||||
|
->getForm(); |
||||||
|
|
||||||
|
$form->handleRequest($request); |
||||||
|
$articles = []; |
||||||
|
if ($form->isSubmitted() && $form->isValid()) { |
||||||
|
$feedUrl = $form->get('feedUrl')->getData(); |
||||||
|
$magazineSlug = $form->get('magazine')->getData(); |
||||||
|
$feed = $rssFeedService->fetchFeed($feedUrl); |
||||||
|
$articles = $feed['items'] ?? []; |
||||||
|
$request->getSession()->set('rss_articles', $articles); |
||||||
|
$request->getSession()->set('selected_magazine', $magazineSlug); |
||||||
|
return $this->redirectToRoute('admin_rss_review'); |
||||||
|
} |
||||||
|
|
||||||
|
return $this->render('admin/rss_submit.html.twig', [ |
||||||
|
'form' => $form->createView(), |
||||||
|
'magazines' => $filteredMagazines, |
||||||
|
]); |
||||||
|
} |
||||||
|
|
||||||
|
#[Route('/admin/rss/review', name: 'admin_rss_review', methods: ['GET', 'POST'])] |
||||||
|
public function reviewRssArticles(Request $request, RssToNostrConverter $converter): Response |
||||||
|
{ |
||||||
|
$articles = $request->getSession()->get('rss_articles', []); |
||||||
|
$drafts = []; |
||||||
|
foreach ($articles as $item) { |
||||||
|
$drafts[] = $converter->convertToNostrEvent($item); |
||||||
|
} |
||||||
|
|
||||||
|
if ($request->isMethod('POST')) { |
||||||
|
$toSign = $request->request->all('sign'); |
||||||
|
$signed = []; |
||||||
|
foreach ($toSign as $idx) { |
||||||
|
if (isset($drafts[$idx])) { |
||||||
|
// Here, you would sign and persist the article |
||||||
|
// For now, just collect for confirmation |
||||||
|
$signed[] = $drafts[$idx]; |
||||||
|
} |
||||||
|
} |
||||||
|
// TODO: Persist signed articles as needed |
||||||
|
$this->addFlash('success', count($signed) . ' articles signed and published.'); |
||||||
|
$request->getSession()->remove('rss_articles'); |
||||||
|
return $this->redirectToRoute('admin_rss_submit'); |
||||||
|
} |
||||||
|
|
||||||
|
return $this->render('admin/rss_review.html.twig', [ |
||||||
|
'drafts' => $drafts, |
||||||
|
]); |
||||||
|
} |
||||||
|
|
||||||
|
// Add a route for signing and persisting selected articles as needed |
||||||
|
} |
||||||
@ -1,6 +1,6 @@ |
|||||||
<?php |
<?php |
||||||
|
|
||||||
namespace App\Service; |
namespace App\Service\RSS; |
||||||
|
|
||||||
use Psr\Log\LoggerInterface; |
use Psr\Log\LoggerInterface; |
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface; |
use Symfony\Contracts\HttpClient\HttpClientInterface; |
||||||
@ -1,6 +1,6 @@ |
|||||||
<?php |
<?php |
||||||
|
|
||||||
namespace App\Service; |
namespace App\Service\RSS; |
||||||
|
|
||||||
use Psr\Log\LoggerInterface; |
use Psr\Log\LoggerInterface; |
||||||
|
|
||||||
Loading…
Reference in new issue