You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
5.1 KiB
147 lines
5.1 KiB
<?php |
|
|
|
namespace App\Service; |
|
|
|
use App\Entity\Nzine; |
|
use App\Entity\NzineBot; |
|
use App\Entity\Event as EventEntity; |
|
use App\Entity\User; |
|
use App\Enum\KindsEnum; |
|
use App\Enum\RolesEnum; |
|
use swentel\nostr\Event\Event; |
|
use swentel\nostr\Key\Key; |
|
use swentel\nostr\Sign\Sign; |
|
use Symfony\Component\Serializer\Encoder\JsonEncoder; |
|
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; |
|
use Symfony\Component\Serializer\Serializer; |
|
use Symfony\Component\String\Slugger\AsciiSlugger; |
|
use Symfony\Component\Workflow\WorkflowInterface; |
|
use Doctrine\ORM\EntityManagerInterface; |
|
|
|
class NzineWorkflowService |
|
{ |
|
private Nzine $nzine; |
|
|
|
public function __construct(private readonly WorkflowInterface $nzineWorkflow, |
|
private readonly NostrClient $nostrClient, |
|
private readonly EncryptionService $encryptionService, |
|
private readonly EntityManagerInterface $entityManager) |
|
{ |
|
} |
|
|
|
public function init($nzine = null): Nzine |
|
{ |
|
if (!is_null($nzine)) { |
|
$this->nzine = $nzine; |
|
} else { |
|
$this->nzine = new Nzine(); |
|
} |
|
|
|
return $this->nzine; |
|
} |
|
|
|
public function createProfile($nzine, $name, $about, $user): Nzine |
|
{ |
|
if (!$this->nzineWorkflow->can($nzine, 'create_profile')) { |
|
throw new \LogicException('Cannot create profile in the current state.'); |
|
} |
|
|
|
$this->nzine = $nzine; |
|
|
|
// create NZine bot |
|
$key = new Key(); |
|
$private_key = $key->generatePrivateKey(); |
|
$bot = new NzineBot(); |
|
$bot->setEncryptionService($this->encryptionService); |
|
$bot->setNsec($private_key); |
|
$this->entityManager->persist($bot); |
|
$this->entityManager->flush(); |
|
|
|
// publish bot profile |
|
$profileContent = [ |
|
'name' => $name, |
|
'about' => $about, |
|
'bot' => true |
|
]; |
|
$profileEvent = new Event(); |
|
$profileEvent->setKind(KindsEnum::METADATA->value); |
|
$profileEvent->setContent(json_encode($profileContent)); |
|
$signer = new Sign(); |
|
$signer->signEvent($profileEvent, $private_key); |
|
// $this->nostrClient->publishEvent($profileEvent, ['wss://purplepag.es']); |
|
|
|
// add EDITOR role to the user |
|
$role = RolesEnum::EDITOR->value; |
|
$user = $this->entityManager->getRepository(User::class)->findOneBy(['npub' => $user->getUserIdentifier()]); |
|
$user->addRole($role); |
|
$this->entityManager->persist($user); |
|
|
|
// create NZine entity |
|
$public_key = $key->getPublicKey($private_key); |
|
$this->nzine->setNpub($public_key); |
|
$this->nzine->setNzineBot($bot); |
|
$this->nzine->setEditor($user->getUserIdentifier()); |
|
$this->nzineWorkflow->apply($this->nzine, 'create_profile'); |
|
$this->entityManager->persist($this->nzine); |
|
$this->entityManager->flush(); |
|
|
|
return $this->nzine; |
|
} |
|
|
|
/** |
|
* @throws \JsonException |
|
*/ |
|
public function createMainIndex(Nzine $nzine, string $title, string $summary): void |
|
{ |
|
if (!$this->nzineWorkflow->can($nzine, 'create_main_index')) { |
|
// throw new \LogicException('Cannot create main index in the current state.'); |
|
} |
|
|
|
$bot = $nzine->getNzineBot(); |
|
$private_key = $bot->getNsec(); |
|
|
|
$slugger = new AsciiSlugger(); |
|
$slug = 'nzine-'.$slugger->slug($title)->lower().'-'.rand(10000,99999); |
|
// save slug to nzine |
|
$nzine->setSlug($slug); |
|
|
|
// create NZine main index |
|
$index = new Event(); |
|
$index->setKind(KindsEnum::PUBLICATION_INDEX->value); |
|
|
|
$index->addTag(['d' => $slug]); |
|
$index->addTag(['title' => $title]); |
|
$index->addTag(['summary' => $summary]); |
|
$index->addTag(['auto-update' => 'yes']); |
|
$index->addTag(['type' => 'magazine']); |
|
$signer = new Sign(); |
|
$signer->signEvent($index, $private_key); |
|
// save to persistence, first map to EventEntity |
|
$serializer = new Serializer([new ObjectNormalizer()],[new JsonEncoder()]); |
|
$i = $serializer->deserialize($index->toJson(), EventEntity::class, 'json'); |
|
$this->entityManager->persist($i); |
|
|
|
$this->nzineWorkflow->apply($nzine, 'create_main_index'); |
|
$this->entityManager->flush(); |
|
} |
|
|
|
public function createNestedIndex(Nzine $nzine, string $categoryTitle, array $tags): void |
|
{ |
|
if (!$this->nzineWorkflow->can($nzine, 'create_nested_indices')) { |
|
throw new \LogicException('Cannot create nested indices in the current state.'); |
|
} |
|
|
|
// Example logic: Create a nested index for the category |
|
$nestedIndex = new EventEntity(); |
|
// $nestedIndex->setTitle($categoryTitle); |
|
$nestedIndex->setTags($tags); |
|
$nestedIndex->setKind('30040'); // Assuming 30040 is the kind for publication indices |
|
|
|
$this->entityManager->persist($nestedIndex); |
|
|
|
$this->nzineWorkflow->apply($nzine, 'create_nested_indices'); |
|
$this->entityManager->persist($nzine); |
|
$this->entityManager->flush(); |
|
} |
|
} |
|
|
|
|