Passed
Push — master ( 017cdc...ca97c4 )
by Yannick
08:28
created

CLinkImageController::__invoke()   B

Complexity

Conditions 8
Paths 58

Size

Total Lines 52
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 33
nc 58
nop 2
dl 0
loc 52
rs 8.1475
c 1
b 0
f 0

How to fix   Long Method   

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\Asset;
10
use Chamilo\CourseBundle\Entity\CLink;
11
use Doctrine\ORM\EntityManagerInterface;
12
use Symfony\Component\HttpFoundation\File\File;
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\HttpFoundation\Response;
15
16
class CLinkImageController
17
{
18
    private EntityManagerInterface $entityManager;
19
20
    public function __construct(EntityManagerInterface $entityManager)
21
    {
22
        $this->entityManager = $entityManager;
23
    }
24
25
    public function __invoke(CLink $link, Request $request): Response
26
    {
27
        $removeImage = $request->request->getBoolean('removeImage', false);
28
        $file = $request->files->get('customImage');
29
30
        if ($removeImage) {
31
            if ($link->getCustomImage()) {
32
                $this->entityManager->remove($link->getCustomImage());
33
                $link->setCustomImage(null);
34
                $this->entityManager->persist($link);
35
                $this->entityManager->flush();
36
37
                if (!$file) {
38
                    return new Response('Image removed successfully', Response::HTTP_OK);
39
                }
40
            }
41
        }
42
43
        if (!$file || !$file->isValid()) {
44
            return new Response('Invalid or missing file', Response::HTTP_BAD_REQUEST);
45
        }
46
47
        try {
48
            $asset = new Asset();
49
            $asset->setFile($file)
50
                ->setCategory(Asset::LINK)
51
                ->setTitle($file->getClientOriginalName());
52
53
            $this->entityManager->persist($asset);
54
            $this->entityManager->flush();
55
56
            $uploadedFilePath = $file->getPathname();
57
58
            $croppedFilePath = $this->cropImage($uploadedFilePath);
59
60
            if (!file_exists($croppedFilePath)) {
61
                @unlink($uploadedFilePath);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

61
                /** @scrutinizer ignore-unhandled */ @unlink($uploadedFilePath);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
62
                return new Response('Error creating cropped image', Response::HTTP_INTERNAL_SERVER_ERROR);
63
            }
64
65
            $asset->setFile(new File($croppedFilePath));
66
            $this->entityManager->persist($asset);
67
            $this->entityManager->flush();
68
69
            $link->setCustomImage($asset);
70
            $this->entityManager->persist($link);
71
            $this->entityManager->flush();
72
73
            return new Response('Image uploaded and linked successfully', Response::HTTP_OK);
74
75
        } catch (\Exception $e) {
76
            return new Response('Error processing image: ' . $e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
77
        }
78
    }
79
80
    private function cropImage(string $filePath): string
81
    {
82
        [$originalWidth, $originalHeight, $imageType] = getimagesize($filePath);
83
84
        if (!$originalWidth || !$originalHeight) {
85
            throw new \RuntimeException('Invalid image file');
86
        }
87
88
        switch ($imageType) {
89
            case IMAGETYPE_JPEG:
90
                $sourceImage = imagecreatefromjpeg($filePath);
91
                break;
92
            case IMAGETYPE_PNG:
93
                $sourceImage = imagecreatefrompng($filePath);
94
                break;
95
            case IMAGETYPE_GIF:
96
                $sourceImage = imagecreatefromgif($filePath);
97
                break;
98
            default:
99
                throw new \RuntimeException('Unsupported image type');
100
        }
101
102
        $croppedImage = imagecreatetruecolor(120, 120);
103
104
        $cropWidth = min($originalWidth, $originalHeight);
105
        $cropHeight = $cropWidth;
106
        $srcX = (int) (($originalWidth - $cropWidth) / 2);
107
        $srcY = (int) (($originalHeight - $cropHeight) / 2);
108
109
        imagecopyresampled(
110
            $croppedImage,
111
            $sourceImage,
112
            0, 0,
113
            $srcX, $srcY,
114
            $cropWidth, $cropHeight,
115
            120, 120
116
        );
117
118
        $croppedFilePath = sys_get_temp_dir() . '/' . uniqid('cropped_', true) . '.png';
119
        imagepng($croppedImage, $croppedFilePath);
120
121
        imagedestroy($sourceImage);
122
        imagedestroy($croppedImage);
123
124
        return $croppedFilePath;
125
    }
126
}
127