Passed
Push — master ( 719760...59ab2e )
by Angel Fernando Quiroz
18:35
created

ImportCGlossaryAction   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 75
c 0
b 0
f 0
dl 0
loc 120
rs 10
wmc 26

1 Method

Rating   Name   Duplication   Size   Complexity  
F __invoke() 0 113 26
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chamilo\CoreBundle\Controller\Api;
6
7
use Chamilo\CoreBundle\Entity\Course;
8
use Chamilo\CoreBundle\Entity\Session;
9
use Chamilo\CourseBundle\Entity\CGlossary;
10
use Chamilo\CourseBundle\Repository\CGlossaryRepository;
11
use Doctrine\ORM\EntityManager;
12
use Doctrine\ORM\Exception\NotSupported;
13
use Doctrine\ORM\NonUniqueResultException;
14
use Exception;
15
use PhpOffice\PhpSpreadsheet\IOFactory;
16
use Symfony\Component\HttpFoundation\File\UploadedFile;
17
use Symfony\Component\HttpFoundation\Request;
18
use Symfony\Component\HttpFoundation\Response;
19
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
20
21
class ImportCGlossaryAction
22
{
23
    /**
24
     * @throws NonUniqueResultException
25
     * @throws NotSupported
26
     * @throws Exception
27
     */
28
    public function __invoke(Request $request, CGlossaryRepository $repo, EntityManager $em): Response
29
    {
30
        $file = $request->files->get('file');
31
        $fileType = $request->request->get('file_type');
32
        $replace = $request->request->get('replace');
33
        $update = $request->request->get('update');
34
        $cid = $request->request->get('cid');
35
        $sid = $request->request->get('sid');
36
37
        $course = null;
38
        $session = null;
39
        if (0 !== $cid) {
40
            $course = $em->getRepository(Course::class)->find($cid);
41
        }
42
        if (0 !== $sid) {
43
            $session = $em->getRepository(Session::class)->find($sid);
44
        }
45
46
        if (!$file instanceof UploadedFile || !$file->isValid()) {
47
            throw new BadRequestHttpException('Invalid file');
48
        }
49
50
        $data = [];
51
        if ('csv' === $fileType) {
52
            if (($handle = fopen($file->getPathname(), 'r')) !== false) {
53
                $header = fgetcsv($handle, 0, ';');
54
                while (($row = fgetcsv($handle, 0, ';')) !== false) {
55
                    $term = isset($row[0]) ? trim($row[0]) : '';
56
                    $definition = isset($row[1]) ? trim($row[1]) : '';
57
                    $data[$term] = $definition;
58
                }
59
                fclose($handle);
60
            }
61
        } elseif ('xls' === $fileType) {
62
            $spreadsheet = IOFactory::load($file->getPathname());
63
            $sheet = $spreadsheet->getActiveSheet();
64
            $firstRow = true;
65
            foreach ($sheet->getRowIterator() as $row) {
66
                if ($firstRow) {
67
                    $firstRow = false;
68
69
                    continue;
70
                }
71
                $cellIterator = $row->getCellIterator();
72
                $cellIterator->setIterateOnlyExistingCells(false);
73
                $rowData = [];
74
                foreach ($cellIterator as $cell) {
75
                    $rowData[] = $cell->getValue();
76
                }
77
                $term = isset($rowData[0]) ? utf8_decode(trim($rowData[0])) : '';
78
                $definition = isset($rowData[1]) ? utf8_decode(trim($rowData[1])) : '';
79
                $data[$term] = $definition;
80
            }
81
        } else {
82
            throw new BadRequestHttpException('Invalid file type');
83
        }
84
85
        if (empty($data)) {
86
            throw new BadRequestHttpException('Invalid data');
87
        }
88
89
        if ('true' === $replace) {
90
            $qb = $repo->getResourcesByCourse($course, $session);
91
            $allGlossaries = $qb->getQuery()->getResult();
92
            if ($allGlossaries) {
93
                /** @var CGlossary $item */
94
                foreach ($allGlossaries as $item) {
95
                    $termToDelete = $repo->find($item->getIid());
96
                    if (null !== $termToDelete) {
97
                        $repo->delete($termToDelete);
98
                    }
99
                }
100
            }
101
        }
102
103
        if ('true' === $update) {
104
            foreach ($data as $termToUpdate => $descriptionToUpdate) {
105
                // Check if the term already exists
106
                $qb = $repo->getResourcesByCourse($course, $session)
107
                    ->andWhere('resource.name = :name')
108
                    ->setParameter('name', $termToUpdate)
109
                ;
110
111
                /** @var CGlossary $existingGlossaryTerm */
112
                $existingGlossaryTerm = $qb->getQuery()->getOneOrNullResult();
113
                if (null !== $existingGlossaryTerm) {
114
                    $existingGlossaryTerm->setDescription($descriptionToUpdate);
115
                    $repo->update($existingGlossaryTerm);
116
                    unset($data[$termToUpdate]);
117
                }
118
            }
119
        }
120
121
        foreach ($data as $term => $description) {
122
            $qb = $repo->getResourcesByCourse($course, $session)
123
                ->andWhere('resource.name = :name')
124
                ->setParameter('name', $term)
125
            ;
126
127
            /** @var CGlossary $existingNewGlossaryTerm */
128
            $existingNewGlossaryTerm = $qb->getQuery()->getOneOrNullResult();
129
            if (!$existingNewGlossaryTerm) {
130
                $newGlossary = (new CGlossary())
131
                    ->setName($term)
132
                    ->setDescription($description)
133
                    ->setParent($course)
134
                    ->addCourseLink($course, $session)
135
                ;
136
                $repo->create($newGlossary);
137
            }
138
        }
139
140
        return new Response(json_encode($data), Response::HTTP_OK, ['Content-Type' => 'application/json']);
141
    }
142
}
143