Skip to content

Commit f689326

Browse files
authored
Merge pull request #1270 from superdesk/SWP-2325
Content push with custom status
2 parents 5a1d577 + ea8abe6 commit f689326

File tree

8 files changed

+283
-14
lines changed

8 files changed

+283
-14
lines changed

src/SWP/Bundle/ContentBundle/Controller/ContentPushController.php

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
use Doctrine\ORM\EntityManagerInterface;
2020
use SWP\Bundle\BridgeBundle\Doctrine\ORM\PackageRepository;
21+
use SWP\Bundle\ContentBundle\Doctrine\ArticleRepositoryInterface;
2122
use SWP\Bundle\CoreBundle\Util\MimeTypeHelper;
2223
use SWP\Component\MultiTenancy\Context\TenantContextInterface;
2324
use Symfony\Component\Mime\MimeTypes;
@@ -48,6 +49,7 @@ class ContentPushController extends AbstractController {
4849
private MediaManagerInterface $mediaManager; // swp_content_bundle.manager.media
4950
private EntityManagerInterface $entityManager; // swp.object_manager.media
5051
private PackageRepository $packageRepository;//swp.repository.package
52+
private ArticleRepositoryInterface $articleRepository;//swp.repository.article
5153
private FileProviderInterface $fileProvider;
5254

5355
/**
@@ -58,20 +60,28 @@ class ContentPushController extends AbstractController {
5860
* @param MediaManagerInterface $mediaManager
5961
* @param EntityManagerInterface $entityManager
6062
* @param PackageRepository $packageRepository
63+
* @param ArticleRepositoryInterface $articleRepository
6164
* @param FileProviderInterface $fileProvider
6265
*/
63-
public function __construct(EventDispatcherInterface $eventDispatcher, FormFactoryInterface $formFactory,
64-
MessageBusInterface $messageBus,
65-
DataTransformerInterface $dataTransformer, MediaManagerInterface $mediaManager,
66-
EntityManagerInterface $entityManager, PackageRepository $packageRepository,
67-
FileProviderInterface $fileProvider) {
66+
public function __construct(
67+
EventDispatcherInterface $eventDispatcher,
68+
FormFactoryInterface $formFactory,
69+
MessageBusInterface $messageBus,
70+
DataTransformerInterface $dataTransformer,
71+
MediaManagerInterface $mediaManager,
72+
EntityManagerInterface $entityManager,
73+
PackageRepository $packageRepository,
74+
ArticleRepositoryInterface $articleRepository,
75+
FileProviderInterface $fileProvider
76+
) {
6877
$this->eventDispatcher = $eventDispatcher;
6978
$this->formFactory = $formFactory;
7079
$this->messageBus = $messageBus;
7180
$this->dataTransformer = $dataTransformer;
7281
$this->mediaManager = $mediaManager;
7382
$this->entityManager = $entityManager;
7483
$this->packageRepository = $packageRepository;
84+
$this->articleRepository = $articleRepository;
7585
$this->fileProvider = $fileProvider;
7686
}
7787

@@ -85,11 +95,39 @@ public function pushContentAction(Request $request, TenantContextInterface $tena
8595

8696
$currentTenant = $tenantContext->getTenant();
8797

88-
$this->messageBus->dispatch(new ContentPushMessage($currentTenant->getId(), $request->getContent()));
98+
$this->messageBus->dispatch(
99+
new ContentPushMessage($currentTenant->getId(), $request->getContent())
100+
);
89101

90102
return new SingleResourceResponse(['status' => 'OK'], new ResponseContext(201));
91103
}
92104

105+
106+
/**
107+
* @Route("/api/{version}/content/push-with-options", methods={"POST"}, options={"expose"=true}, defaults={"version"="v2"}, name="swp_api_content_push_with_status")
108+
*/
109+
public function pushContentWithOptionsAction(
110+
Request $request,
111+
TenantContextInterface $tenantContext
112+
): SingleResourceResponseInterface {
113+
$status = $request->query->get('status', '');
114+
$request->getQueryString();
115+
$package = $this->dataTransformer->transform($request->getContent());
116+
$this->eventDispatcher->dispatch(new GenericEvent($package), Events::SWP_VALIDATION);
117+
118+
$currentTenant = $tenantContext->getTenant();
119+
120+
$options = [];
121+
if (!empty($status)) {
122+
$options['status'] = $status;
123+
}
124+
$this->messageBus->dispatch(
125+
new ContentPushMessage($currentTenant->getId(), $request->getContent(), $options)
126+
);
127+
128+
return new SingleResourceResponse(['status' => 'OK'], new ResponseContext(201));
129+
}
130+
93131
/**
94132
* @Route("/api/{version}/assets/push", methods={"POST"}, options={"expose"=true}, defaults={"version"="v2"}, name="swp_api_assets_push")
95133
*/

src/SWP/Bundle/ContentBundle/Resources/config/controllers.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ services:
2626
$mediaManager: '@swp_content_bundle.manager.media'
2727
$entityManager: '@swp.object_manager.media'
2828
$packageRepository: '@swp.repository.package'
29+
$articleRepository: '@swp.repository.article'
2930

3031
SWP\Bundle\ContentBundle\Controller\MediaController: ~
3132
SWP\Bundle\ContentBundle\Controller\RelatedArticleController:
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<?php
2+
3+
namespace SWP\Bundle\CoreBundle\EventListener;
4+
5+
use Doctrine\ORM\EntityManagerInterface;
6+
use Psr\Log\LoggerInterface;
7+
use SWP\Bundle\ContentBundle\ArticleEvents;
8+
use SWP\Bundle\ContentBundle\Doctrine\ArticleRepositoryInterface;
9+
use SWP\Bundle\ContentBundle\Event\ArticleEvent;
10+
use SWP\Bundle\CoreBundle\Model\Package;
11+
use SWP\Bundle\CoreBundle\Model\PackageInterface;
12+
use SWP\Bundle\CoreBundle\Model\PublishDestination;
13+
use SWP\Bundle\CoreBundle\Provider\PublishDestinationProvider;
14+
use SWP\Bundle\MultiTenancyBundle\MultiTenancyEvents;
15+
use SWP\Component\Common\Exception\UnexpectedTypeException;
16+
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
17+
use Symfony\Component\EventDispatcher\GenericEvent;
18+
19+
final class PackageOptionsListener
20+
{
21+
protected $publishDestinationManager;
22+
protected $packageManager;
23+
protected $articleManager;
24+
25+
protected EntityManagerInterface $entityManager;
26+
protected PublishDestinationProvider $publishDestinationProvider;
27+
28+
private ArticleRepositoryInterface $articleRepository;
29+
30+
private EventDispatcherInterface $eventDispatcher;
31+
32+
33+
protected ?LoggerInterface $logger;
34+
35+
public function __construct(
36+
$publishDestinationManager,
37+
$packageManager,
38+
ArticleRepositoryInterface $articleRepository,
39+
$articleManager,
40+
PublishDestinationProvider $publishDestinationProvider,
41+
EventDispatcherInterface $eventDispatcher,
42+
) {
43+
$this->publishDestinationManager = $publishDestinationManager;
44+
$this->packageManager = $packageManager;
45+
$this->articleManager = $articleManager;
46+
47+
$this->publishDestinationProvider = $publishDestinationProvider;
48+
$this->articleRepository = $articleRepository;
49+
$this->eventDispatcher = $eventDispatcher;
50+
}
51+
52+
53+
private function getPackage(GenericEvent $event): ?PackageInterface
54+
{
55+
return $event->getSubject()['package'] ?? null;
56+
}
57+
58+
private function getOptions(GenericEvent $event): array
59+
{
60+
return $event->getSubject()['options'] ?? [];
61+
}
62+
63+
public function setLogger(LoggerInterface $logger)
64+
{
65+
$this->logger = $logger;
66+
}
67+
68+
public function postPackageOptions(GenericEvent $event)
69+
{
70+
$package = $this->getPackage($event);
71+
$options = $this->getOptions($event);
72+
73+
$status = $options['status'] ?? '';
74+
if (!empty($status)) {
75+
$this->setArticlesStatus($package, $status);
76+
$this->setPackageStatus($package, $status);
77+
}
78+
79+
}
80+
81+
public function prePackageOptions(GenericEvent $event)
82+
{
83+
$package = $this->getPackage($event);
84+
85+
/**
86+
* Delete all destinations
87+
*/
88+
$this->deleteDestinations($package);
89+
/**
90+
* Remove service part from package
91+
*/
92+
$this->clearPackageServices($package);
93+
}
94+
public function deleteDestinations($package): void
95+
{
96+
$this->eventDispatcher->dispatch(new GenericEvent(), MultiTenancyEvents::TENANTABLE_DISABLE);
97+
$destinations = $this->publishDestinationProvider->getDestinations($package);
98+
99+
/**
100+
* @var PublishDestination $destination
101+
*/
102+
foreach ($destinations as $destination) {
103+
$this->publishDestinationManager->remove($destination);
104+
}
105+
$this->publishDestinationManager->flush();
106+
$this->eventDispatcher->dispatch(new GenericEvent(), MultiTenancyEvents::TENANTABLE_ENABLE);
107+
}
108+
109+
private function clearPackageServices(Package $package)
110+
{
111+
$this->eventDispatcher->dispatch(new GenericEvent(), MultiTenancyEvents::TENANTABLE_DISABLE);
112+
$package->setServices();
113+
$this->packageManager->persist($package);
114+
$this->packageManager->flush();
115+
$this->eventDispatcher->dispatch(new GenericEvent(), MultiTenancyEvents::TENANTABLE_ENABLE);
116+
}
117+
118+
private function setArticlesStatus(PackageInterface $package, string $status)
119+
{
120+
$this->eventDispatcher->dispatch(new GenericEvent(), MultiTenancyEvents::TENANTABLE_DISABLE);
121+
$articles = $this->articleRepository
122+
->getArticlesByPackage($package)
123+
->getQuery()
124+
->getResult();
125+
126+
foreach ($articles as $article) {
127+
$article->setStatus($status);
128+
$this->articleManager->flush();
129+
}
130+
131+
$this->eventDispatcher->dispatch(new GenericEvent(), MultiTenancyEvents::TENANTABLE_ENABLE);
132+
}
133+
134+
private function setPackageStatus(Package $package, string $status)
135+
{
136+
$this->eventDispatcher->dispatch(new GenericEvent(), MultiTenancyEvents::TENANTABLE_DISABLE);
137+
$package->setStatus($status);
138+
$this->packageManager->persist($package);
139+
$this->packageManager->flush();
140+
$this->eventDispatcher->dispatch(new GenericEvent(), MultiTenancyEvents::TENANTABLE_ENABLE);
141+
}
142+
}

src/SWP/Bundle/CoreBundle/MessageHandler/AbstractContentPushHandler.php

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public function __construct(
7979
$this->lockFactory = $lockFactory;
8080
}
8181

82-
public function execute(int $tenantId, PackageInterface $package): void
82+
public function execute(int $tenantId, PackageInterface $package, array $options = []): void
8383
{
8484
$lock = $this->lockFactory->createLock($this->generateLockId($package->getGuid()), 120);
8585

@@ -88,7 +88,7 @@ public function execute(int $tenantId, PackageInterface $package): void
8888
throw new LockConflictedException();
8989
}
9090

91-
$this->doExecute($tenantId, $package);
91+
$this->doExecute($tenantId, $package, $options);
9292
} catch (UniqueConstraintViolationException $e) {
9393
$this->logException($e, $package, 'UniqueConstraintViolationException exception');
9494

@@ -119,7 +119,7 @@ private function generateLockId(string $guid): string
119119
return md5(json_encode(['type' => 'package', 'guid' => $guid]));
120120
}
121121

122-
private function doExecute(int $tenantId, PackageInterface $package): void
122+
private function doExecute(int $tenantId, PackageInterface $package, array $options = []): void
123123
{
124124
$packageType = $package->getType();
125125
if (ItemInterface::TYPE_TEXT !== $packageType && ItemInterface::TYPE_COMPOSITE !== $packageType) {
@@ -133,22 +133,64 @@ private function doExecute(int $tenantId, PackageInterface $package): void
133133
if (null !== $existingPackage) {
134134
$existingPackage = $this->packageHydrator->hydrate($package, $existingPackage);
135135

136+
if (!empty($options)) {
137+
$this->eventDispatcher->dispatch(
138+
new GenericEvent(
139+
[
140+
'package' => $existingPackage,
141+
'options' => $options,
142+
],
143+
['eventName' => Events::PACKAGE_PRE_OPTIONS]
144+
),
145+
Events::PACKAGE_PRE_OPTIONS);
146+
}
136147
$this->eventDispatcher->dispatch( new GenericEvent($existingPackage, ['eventName' => Events::PACKAGE_PRE_UPDATE]), Events::PACKAGE_PRE_UPDATE);
137148
$this->packageObjectManager->flush();
138149
$this->eventDispatcher->dispatch( new GenericEvent($existingPackage, ['eventName' => Events::PACKAGE_POST_UPDATE]), Events::PACKAGE_POST_UPDATE);
139150
$this->eventDispatcher->dispatch( new GenericEvent($existingPackage, ['eventName' => Events::PACKAGE_PROCESSED]), Events::PACKAGE_PROCESSED);
140151
$this->packageObjectManager->flush();
141152

142-
$this->reset();
143153
$this->logger->info(sprintf('Package %s was updated', $existingPackage->getGuid()));
144154

155+
if (!empty($options)) {
156+
$this->eventDispatcher->dispatch(
157+
new GenericEvent(
158+
['package' => $existingPackage, 'options' => $options],
159+
['eventName' => Events::PACKAGE_POST_OPTIONS]
160+
),
161+
Events::PACKAGE_POST_OPTIONS
162+
);
163+
}
164+
165+
$this->reset();
145166
return;
146167
}
147168

169+
if (!empty($options)) {
170+
$this->eventDispatcher->dispatch(
171+
new GenericEvent(
172+
['package' => $package, 'options' => $options],
173+
['eventName' => Events::PACKAGE_PRE_OPTIONS]
174+
),
175+
Events::PACKAGE_PRE_OPTIONS
176+
);
177+
}
178+
148179
$this->eventDispatcher->dispatch( new GenericEvent($package, ['eventName' => Events::PACKAGE_PRE_CREATE]), Events::PACKAGE_PRE_CREATE);
149180
$this->packageRepository->add($package);
150181
$this->eventDispatcher->dispatch( new GenericEvent($package, ['eventName' => Events::PACKAGE_POST_CREATE]), Events::PACKAGE_POST_CREATE);
151182
$this->eventDispatcher->dispatch( new GenericEvent($package, ['eventName' => Events::PACKAGE_PROCESSED]), Events::PACKAGE_PROCESSED);
183+
184+
if (!empty($options)) {
185+
$this->eventDispatcher->dispatch(
186+
new GenericEvent(
187+
['package' => $package, 'options' => $options],
188+
['eventName' => Events::PACKAGE_POST_OPTIONS]
189+
),
190+
Events::PACKAGE_POST_OPTIONS
191+
);
192+
}
193+
152194
$this->packageObjectManager->flush();
153195

154196
$this->logger->info(sprintf('Package %s was created', $package->getGuid()));

src/SWP/Bundle/CoreBundle/MessageHandler/ContentPushHandler.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ public function __invoke(ContentPushMessage $contentPushMessage)
2525
$content = $contentPushMessage->getContent();
2626
$tenantId = $contentPushMessage->getTenantId();
2727
$package = $this->jsonToPackageTransformer->transform($content);
28+
$options = $contentPushMessage->getOptions();
2829

29-
$this->execute($tenantId, $package);
30+
$this->execute($tenantId, $package, $options);
3031
}
3132
}

src/SWP/Bundle/CoreBundle/MessageHandler/Message/ContentPushMessage.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ class ContentPushMessage implements MessageInterface
2323

2424
/** @var string */
2525
private $content;
26+
protected array $options = [];
2627

27-
public function __construct(int $tenantId, string $content)
28+
public function __construct(int $tenantId, string $content, array $options = [])
2829
{
2930
$this->tenantId = $tenantId;
3031
$this->content = $content;
32+
$this->options = $options;
3133
}
3234

3335
public function getTenantId(): int
@@ -40,11 +42,20 @@ public function getContent(): string
4042
return $this->content;
4143
}
4244

45+
/**
46+
* @return array
47+
*/
48+
public function getOptions(): array
49+
{
50+
return $this->options;
51+
}
52+
4353
public function toArray(): array
4454
{
4555
return [
46-
'tenant' => $this->tenantId,
47-
'content' => $this->content,
56+
'tenant' => $this->tenantId,
57+
'content' => $this->content,
58+
'options' => $this->options
4859
];
4960
}
5061
}

0 commit comments

Comments
 (0)