Completed
Push — master ( 91f8d1...9dd64d )
by
unknown
01:55 queued 39s
created

MoveDocumentAction::__invoke()   C

Complexity

Conditions 16
Paths 108

Size

Total Lines 81
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 16
eloc 51
nc 108
nop 2
dl 0
loc 81
rs 5.5
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Controller\Api;
8
9
use Chamilo\CoreBundle\Entity\Course;
10
use Chamilo\CoreBundle\Entity\ResourceLink;
11
use Chamilo\CoreBundle\Entity\ResourceNode;
12
use Chamilo\CoreBundle\Entity\Session;
13
use Chamilo\CoreBundle\Repository\ResourceLinkRepository;
14
use Chamilo\CourseBundle\Entity\CGroup;
15
use Chamilo\CourseBundle\Entity\CDocument;
16
use Doctrine\ORM\EntityManagerInterface;
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
19
20
final class MoveDocumentAction
21
{
22
    public function __construct(
23
        private EntityManagerInterface $em,
24
        private ResourceLinkRepository $linkRepo,
25
    ) {}
26
27
    public function __invoke(CDocument $document, Request $request): CDocument
28
    {
29
        $payload = json_decode((string) $request->getContent(), true);
30
        if (!is_array($payload)) {
31
            throw new BadRequestHttpException('Invalid JSON body.');
32
        }
33
34
        $rawParent = $payload['parentResourceNodeId'] ?? null;
35
        if (null === $rawParent || '' === $rawParent) {
36
            throw new BadRequestHttpException('Missing "parentResourceNodeId".');
37
        }
38
39
        $destNodeId = $this->normalizeNodeId($rawParent);
40
        if (null === $destNodeId) {
41
            throw new BadRequestHttpException('Invalid "parentResourceNodeId".');
42
        }
43
44
        $cid = $request->query->getInt('cid', 0);
45
        $sid = $request->query->getInt('sid', 0);
46
        $gid = $request->query->getInt('gid', 0);
47
48
        $hasContext = $cid > 0 || $sid > 0 || $gid > 0;
49
50
        /** @var ResourceNode|null $destNode */
51
        $destNode = $this->em->getRepository(ResourceNode::class)->find($destNodeId);
52
        if (!$destNode) {
53
            throw new BadRequestHttpException('Destination folder node not found.');
54
        }
55
56
        $docNode = $document->getResourceNode();
57
        if (!$docNode) {
58
            throw new BadRequestHttpException('Document resource node not found.');
59
        }
60
61
        if ($hasContext) {
62
            $course = $cid > 0 ? $this->em->getRepository(Course::class)->find($cid) : null;
63
            $session = $sid > 0 ? $this->em->getRepository(Session::class)->find($sid) : null;
64
            $group = $gid > 0 ? $this->em->getRepository(CGroup::class)->find($gid) : null;
65
66
            $docLink = $this->linkRepo->findParentLinkForContext(
67
                $docNode,
68
                $course,
69
                $session,
70
                $group,
71
                null,
72
                null
73
            );
74
75
            if (!$docLink instanceof ResourceLink) {
76
                throw new BadRequestHttpException('Document has no link in this context.');
77
            }
78
79
            $destLink = $this->linkRepo->findParentLinkForContext(
80
                $destNode,
81
                $course,
82
                $session,
83
                $group,
84
                null,
85
                null
86
            );
87
88
            if (!$destLink instanceof ResourceLink) {
89
                throw new BadRequestHttpException('Destination folder has no link in this context.');
90
            }
91
92
            if ($docLink->getId() === $destLink->getId()) {
93
                throw new BadRequestHttpException('Cannot move into itself.');
94
            }
95
96
            $docLink->setParent($destLink);
97
            $this->em->persist($docLink);
98
            $this->em->flush();
99
100
            return $document;
101
        }
102
103
        $docNode->setParent($destNode);
104
        $this->em->persist($docNode);
105
        $this->em->flush();
106
107
        return $document;
108
    }
109
110
    private function normalizeNodeId(mixed $value): ?int
111
    {
112
        if (is_int($value)) {
113
            return $value;
114
        }
115
116
        if (is_string($value)) {
117
            if (ctype_digit($value)) {
118
                return (int) $value;
119
            }
120
121
            if (preg_match('#/api/resource_nodes/(\d+)#', $value, $m)) {
122
                return (int) $m[1];
123
            }
124
        }
125
126
        return null;
127
    }
128
}
129