Completed
Push — 5.0 ( af856a...a5c72a )
by Ruud
13:29
created

NodeAdminPublisher::chooseHowToPublish()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 22
Code Lines 14

Duplication

Lines 22
Ratio 100 %

Importance

Changes 0
Metric Value
dl 22
loc 22
rs 9.2
c 0
b 0
f 0
cc 3
eloc 14
nc 2
nop 3
1
<?php
2
3
namespace Kunstmaan\NodeBundle\Helper\NodeAdmin;
4
5
use Doctrine\ORM\EntityManager;
6
use Kunstmaan\AdminBundle\Entity\BaseUser;
7
use Kunstmaan\AdminBundle\Helper\CloneHelper;
8
use Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionMap;
9
use Kunstmaan\NodeBundle\Entity\HasNodeInterface;
10
use Kunstmaan\NodeBundle\Entity\Node;
11
use Kunstmaan\NodeBundle\Entity\NodeTranslation;
12
use Kunstmaan\NodeBundle\Entity\NodeVersion;
13
use Kunstmaan\NodeBundle\Entity\QueuedNodeTranslationAction;
14
use Kunstmaan\NodeBundle\Event\Events;
15
use Kunstmaan\NodeBundle\Event\NodeEvent;
16
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpFoundation\Session\Session;
19
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
20
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
21
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
22
use Symfony\Component\Translation\TranslatorInterface;
23
use Kunstmaan\AdminBundle\FlashMessages\FlashTypes;
24
25
class NodeAdminPublisher
26
{
27
    /**
28
     * @var EntityManager
29
     */
30
    private $em;
31
32
    /**
33
     * @var TokenStorageInterface
34
     */
35
    private $tokenStorage;
36
37
    /**
38
     * @var AuthorizationCheckerInterface
39
     */
40
    private $authorizationChecker;
41
42
    /**
43
     * @var EventDispatcherInterface
44
     */
45
    private $eventDispatcher;
46
47
    /**
48
     * @var CloneHelper
49
     */
50
    private $cloneHelper;
51
52
    /**
53
     * @param EntityManager                  $em                    The entity manager
54
     * @param TokenStorageInterface          $tokenStorage          The security token storage
55
     * @param AuthorizationCheckerInterface  $authorizationChecker  The security authorization checker
56
     * @param EventDispatcherInterface       $eventDispatcher       The Event dispatcher
57
     * @param CloneHelper                    $cloneHelper           The clone helper
58
     */
59
    public function __construct(
60
        EntityManager $em,
0 ignored issues
show
Bug introduced by
You have injected the EntityManager via parameter $em. This is generally not recommended as it might get closed and become unusable. Instead, it is recommended to inject the ManagerRegistry and retrieve the EntityManager via getManager() each time you need it.

The EntityManager might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:

function someFunction(ManagerRegistry $registry) {
    $em = $registry->getManager();
    $em->getConnection()->beginTransaction();
    try {
        // Do something.
        $em->getConnection()->commit();
    } catch (\Exception $ex) {
        $em->getConnection()->rollback();
        $em->close();

        throw $ex;
    }
}

If that code throws an exception and the EntityManager is closed. Any other code which depends on the same instance of the EntityManager during this request will fail.

On the other hand, if you instead inject the ManagerRegistry, the getManager() method guarantees that you will always get a usable manager instance.

Loading history...
61
        TokenStorageInterface $tokenStorage,
62
        AuthorizationCheckerInterface $authorizationChecker,
63
        EventDispatcherInterface $eventDispatcher,
64
        CloneHelper $cloneHelper
65
    ) {
66
        $this->em                   = $em;
67
        $this->tokenStorage         = $tokenStorage;
68
        $this->authorizationChecker = $authorizationChecker;
69
        $this->eventDispatcher      = $eventDispatcher;
70
        $this->cloneHelper          = $cloneHelper;
71
    }
72
73
    /**
74
     * If there is a draft version it'll try to publish the draft first. Makse snese because if you want to publish the public version you don't publish but you save.
75
     *
76
     * @param NodeTranslation $nodeTranslation
77
     * @param null|BaseUser   $user
78
     *
79
     *  @throws AccessDeniedException
80
     */
81
    public function publish(NodeTranslation $nodeTranslation, $user = null)
82
    {
83
        if (false === $this->authorizationChecker->isGranted(PermissionMap::PERMISSION_PUBLISH,$nodeTranslation->getNode())) {
84
            throw new AccessDeniedException();
85
        }
86
87
        if (is_null($user)) {
88
            $user = $this->tokenStorage->getToken()->getUser();
89
        }
90
91
        $node = $nodeTranslation->getNode();
92
93
        $nodeVersion = $nodeTranslation->getNodeVersion('draft');
94
        if (!is_null($nodeVersion)) {
95
            $page = $nodeVersion->getRef($this->em);
96
            /** @var $nodeVersion NodeVersion */
97
            $nodeVersion     = $this->createPublicVersion($page, $nodeTranslation, $nodeVersion, $user);
0 ignored issues
show
Bug introduced by
It seems like $page defined by $nodeVersion->getRef($this->em) on line 95 can be null; however, Kunstmaan\NodeBundle\Hel...::createPublicVersion() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
98
            $nodeTranslation = $nodeVersion->getNodeTranslation();
99
        } else {
100
            $nodeVersion = $nodeTranslation->getPublicNodeVersion();
101
        }
102
103
        $page = $nodeVersion->getRef($this->em);
104
105
        $this->eventDispatcher->dispatch(
106
            Events::PRE_PUBLISH,
107
            new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
0 ignored issues
show
Bug introduced by
It seems like $page defined by $nodeVersion->getRef($this->em) on line 103 can be null; however, Kunstmaan\NodeBundle\Eve...odeEvent::__construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
108
        );
109
        $nodeTranslation
110
            ->setOnline(true)
111
            ->setPublicNodeVersion($nodeVersion)
112
            ->setUpdated(new \DateTime());
113
        $this->em->persist($nodeTranslation);
114
        $this->em->flush();
115
116
        // Remove scheduled task
117
        $this->unSchedulePublish($nodeTranslation);
118
119
        $this->eventDispatcher->dispatch(
120
            Events::POST_PUBLISH,
121
            new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
0 ignored issues
show
Bug introduced by
It seems like $page defined by $nodeVersion->getRef($this->em) on line 103 can be null; however, Kunstmaan\NodeBundle\Eve...odeEvent::__construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
122
        );
123
    }
124
125
    /**
126
     * @param NodeTranslation $nodeTranslation The NodeTranslation
127
     * @param \DateTime       $date            The date to publish
128
     *
129
     * @throws AccessDeniedException
130
     */
131 View Code Duplication
    public function publishLater(NodeTranslation $nodeTranslation, \DateTime $date)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
132
    {
133
        $node = $nodeTranslation->getNode();
134
        if (false === $this->authorizationChecker->isGranted(PermissionMap::PERMISSION_PUBLISH, $node)) {
135
            throw new AccessDeniedException();
136
        }
137
138
        //remove existing first
139
        $this->unSchedulePublish($nodeTranslation);
140
141
        $user                        = $this->tokenStorage->getToken()->getUser();
142
        $queuedNodeTranslationAction = new QueuedNodeTranslationAction();
143
        $queuedNodeTranslationAction
144
            ->setNodeTranslation($nodeTranslation)
145
            ->setAction(QueuedNodeTranslationAction::ACTION_PUBLISH)
146
            ->setUser($user)
147
            ->setDate($date);
148
        $this->em->persist($queuedNodeTranslationAction);
149
        $this->em->flush();
150
    }
151
152
    /**
153
     * @param NodeTranslation $nodeTranslation
154
     *
155
     * @throws AccessDeniedException
156
     */
157
    public function unPublish(NodeTranslation $nodeTranslation)
158
    {
159
        if (false === $this->authorizationChecker->isGranted(PermissionMap::PERMISSION_UNPUBLISH,$nodeTranslation->getNode())) {
160
            throw new AccessDeniedException();
161
        }
162
163
        $node        = $nodeTranslation->getNode();
164
        $nodeVersion = $nodeTranslation->getPublicNodeVersion();
165
        $page        = $nodeVersion->getRef($this->em);
166
167
        $this->eventDispatcher->dispatch(
168
            Events::PRE_UNPUBLISH,
169
            new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
0 ignored issues
show
Bug introduced by
It seems like $page defined by $nodeVersion->getRef($this->em) on line 165 can be null; however, Kunstmaan\NodeBundle\Eve...odeEvent::__construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
170
        );
171
        $nodeTranslation->setOnline(false);
172
        $this->em->persist($nodeTranslation);
173
        $this->em->flush();
174
175
        // Remove scheduled task
176
        $this->unSchedulePublish($nodeTranslation);
177
178
        $this->eventDispatcher->dispatch(
179
            Events::POST_UNPUBLISH,
180
            new NodeEvent($node, $nodeTranslation, $nodeVersion, $page)
0 ignored issues
show
Bug introduced by
It seems like $page defined by $nodeVersion->getRef($this->em) on line 165 can be null; however, Kunstmaan\NodeBundle\Eve...odeEvent::__construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
181
        );
182
    }
183
184
    /**
185
     * @param NodeTranslation $nodeTranslation The NodeTranslation
186
     * @param \DateTime       $date            The date to unpublish
187
     *
188
     * @throws AccessDeniedException
189
     */
190 View Code Duplication
    public function unPublishLater(NodeTranslation $nodeTranslation, \DateTime $date)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
191
    {
192
        $node = $nodeTranslation->getNode();
193
        if (false === $this->authorizationChecker->isGranted(PermissionMap::PERMISSION_UNPUBLISH, $node)) {
194
            throw new AccessDeniedException();
195
        }
196
197
        //remove existing first
198
        $this->unSchedulePublish($nodeTranslation);
199
        $user                        = $this->tokenStorage->getToken()->getUser();
200
        $queuedNodeTranslationAction = new QueuedNodeTranslationAction();
201
        $queuedNodeTranslationAction
202
            ->setNodeTranslation($nodeTranslation)
203
            ->setAction(QueuedNodeTranslationAction::ACTION_UNPUBLISH)
204
            ->setUser($user)
205
            ->setDate($date);
206
        $this->em->persist($queuedNodeTranslationAction);
207
        $this->em->flush();
208
    }
209
210
    /**
211
     * @param NodeTranslation $nodeTranslation
212
     */
213
    public function unSchedulePublish(NodeTranslation $nodeTranslation)
214
    {
215
        /* @var Node $node */
216
        $queuedNodeTranslationAction = $this->em->getRepository('KunstmaanNodeBundle:QueuedNodeTranslationAction')
217
            ->findOneBy(array('nodeTranslation' => $nodeTranslation));
218
219
        if (!is_null($queuedNodeTranslationAction)) {
220
            $this->em->remove($queuedNodeTranslationAction);
221
            $this->em->flush();
222
        }
223
    }
224
225
    /**
226
     * This shouldn't be here either but it's an improvement.
227
     *
228
     * @param HasNodeInterface $page            The page
229
     * @param NodeTranslation  $nodeTranslation The node translation
230
     * @param NodeVersion      $nodeVersion     The node version
231
     * @param BaseUser         $user            The user
232
     *
233
     * @return mixed
234
     */
235
    public function createPublicVersion(
236
        HasNodeInterface $page,
237
        NodeTranslation $nodeTranslation,
238
        NodeVersion $nodeVersion,
239
        BaseUser $user
240
    ) {
241
        $newPublicPage  = $this->cloneHelper->deepCloneAndSave($page);
242
        $newNodeVersion = $this->em->getRepository('KunstmaanNodeBundle:NodeVersion')->createNodeVersionFor(
243
            $newPublicPage,
244
            $nodeTranslation,
245
            $user,
246
            $nodeVersion
247
        );
248
249
        $newNodeVersion
250
            ->setOwner($nodeVersion->getOwner())
251
            ->setUpdated($nodeVersion->getUpdated())
252
            ->setCreated($nodeVersion->getCreated());
253
254
        $nodeVersion
255
            ->setOwner($user)
256
            ->setCreated(new \DateTime())
257
            ->setOrigin($newNodeVersion);
258
259
        $this->em->persist($newNodeVersion);
260
        $this->em->persist($nodeVersion);
261
        $this->em->persist($nodeTranslation);
262
        $this->em->flush();
263
        $this->eventDispatcher->dispatch(
264
            Events::CREATE_PUBLIC_VERSION,
265
            new NodeEvent($nodeTranslation->getNode(), $nodeTranslation, $nodeVersion, $newPublicPage)
266
        );
267
268
        return $newNodeVersion;
269
    }
270
271
    /**
272
     * @param Request         $request
273
     * @param NodeTranslation $nodeTranslation
274
     */
275 View Code Duplication
    public function chooseHowToPublish(Request $request, NodeTranslation $nodeTranslation, TranslatorInterface $translator)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
276
    {
277
        /** @var Session $session */
278
        $session = $request->getSession();
279
280
        if ($request->request->has('publish_later') && $request->get('pub_date')) {
281
            $date = new \DateTime(
282
                $request->get('pub_date') . ' ' . $request->get('pub_time')
283
            );
284
            $this->publishLater($nodeTranslation, $date);
285
            $session->getFlashBag()->add(
286
                FlashTypes::SUCCESS,
287
                $translator->trans('kuma_node.admin.publish.flash.success_scheduled')
288
            );
289
        } else {
290
            $this->publish($nodeTranslation);
291
            $session->getFlashBag()->add(
292
                FlashTypes::SUCCESS,
293
                $translator->trans('kuma_node.admin.publish.flash.success_published')
294
            );
295
        }
296
    }
297
298
    /**
299
     * @param Request         $request
300
     * @param NodeTranslation $nodeTranslation
301
     */
302 View Code Duplication
    public function chooseHowToUnpublish(Request $request, NodeTranslation $nodeTranslation, TranslatorInterface $translator)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
303
    {
304
        /** @var Session $session */
305
        $session = $request->getSession();
306
307
        if ($request->request->has('unpublish_later') && $request->get('unpub_date')) {
308
            $date = new \DateTime($request->get('unpub_date') . ' ' . $request->get('unpub_time'));
309
            $this->unPublishLater($nodeTranslation, $date);
310
            $session->getFlashBag()->add(
311
                FlashTypes::SUCCESS,
312
                $translator->trans('kuma_node.admin.unpublish.flash.success_scheduled')
313
            );
314
        } else {
315
            $this->unPublish($nodeTranslation);
316
            $session->getFlashBag()->add(
317
                FlashTypes::SUCCESS,
318
                $translator->trans('kuma_node.admin.unpublish.flash.success_unpublished')
319
            );
320
        }
321
    }
322
}
323