Passed
Push — master ( 89dd8a...a5d151 )
by Angel Fernando Quiroz
10:22
created

ExportCGlossaryAction::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
c 2
b 0
f 0
nc 1
nop 2
dl 0
loc 4
rs 10
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\CoreBundle\Settings\SettingsManager;
10
use Chamilo\CourseBundle\Entity\CGlossary;
11
use Chamilo\CourseBundle\Repository\CGlossaryRepository;
12
use Doctrine\ORM\EntityManager;
13
use Doctrine\ORM\Exception\NotSupported;
14
use Doctrine\ORM\Exception\ORMException;
15
use Doctrine\ORM\OptimisticLockException;
16
use Doctrine\ORM\TransactionRequiredException;
17
use PDF;
18
use PhpOffice\PhpSpreadsheet\Writer\Exception;
19
use Symfony\Component\HttpFoundation\BinaryFileResponse;
20
use Symfony\Component\HttpFoundation\File\File;
21
use Symfony\Component\HttpFoundation\Request;
22
use Symfony\Component\HttpFoundation\Response;
23
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
24
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
25
use Symfony\Contracts\Translation\TranslatorInterface;
26
27
readonly class ExportCGlossaryAction
28
{
29
    public function __construct(
30
        private TranslatorInterface $translator,
31
        private SettingsManager $settingsManager,
32
    ) {}
33
34
    /**
35
     * @throws Exception|NotSupported|ORMException|OptimisticLockException|TransactionRequiredException
36
     */
37
    public function __invoke(
38
        Request $request,
39
        CGlossaryRepository $repo,
40
        EntityManager $em,
41
        TranslatorInterface $translator
42
    ): Response {
43
        $format = $request->get('format');
44
        $cid = $request->request->get('cid');
45
        $sid = $request->request->get('sid');
46
47
        if (!\in_array($format, ['csv', 'xls', 'pdf'], true)) {
48
            throw new BadRequestHttpException('Invalid export format');
49
        }
50
51
        $course = null;
52
        $session = null;
53
        if (0 !== $cid) {
54
            $course = $em->find(Course::class, $cid);
55
        }
56
        if (0 !== $sid) {
57
            $session = $em->find(Session::class, $sid);
58
        }
59
60
        $qb = $repo->getResourcesByCourse($course, $session);
61
        $glossaryItems = $qb->getQuery()->getResult();
62
63
        $exportFilePath = $this->generateExportFile(
64
            $glossaryItems,
65
            $format,
66
            $course,
67
        );
68
69
        $response = new BinaryFileResponse(
70
            new File($exportFilePath)
71
        );
72
        $response->setContentDisposition(
73
            ResponseHeaderBag::DISPOSITION_ATTACHMENT,
74
            $response->getFile()->getFilename()
75
        );
76
77
        return $response;
78
    }
79
80
    /**
81
     * @throws NotSupported|Exception
82
     */
83
    private function generateExportFile(
84
        array $glossaryItems,
85
        string $format,
86
        ?Course $course,
87
    ): string {
88
        if ('pdf' === $format) {
89
            return $this->generatePdfFile($glossaryItems, $course);
90
        }
91
92
        $list = [];
93
        $list[] = ['term', 'definition'];
94
95
        $allowStrip = 'true' === $this->settingsManager->getSetting('glossary.allow_remove_tags_in_glossary_export');
96
97
        foreach ($glossaryItems as $item) {
98
            $definition = $item->getDescription();
99
100
            if ($allowStrip) {
101
                $definition = htmlspecialchars_decode(strip_tags($definition), ENT_QUOTES);
102
            }
103
104
            $list[] = [$item->getTitle(), $definition];
105
        }
106
107
        return match ($format) {
108
            'csv' => $this->generateCsvFile($list, $course),
109
            'xls' => $this->generateExcelFile($list, $course),
110
        };
111
    }
112
113
    private function generateCsvFile(array $glossaryItems, Course $course): string
114
    {
115
        return \Export::arrayToCsv($glossaryItems, 'glossary_course_'.$course->getCode(), true);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Export::arrayToCs...ourse->getCode(), true) could return the type false which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
116
    }
117
118
    private function generateExcelFile(array $glossaryItems, Course $course): string
119
    {
120
        return \Export::arrayToXls($glossaryItems, 'glossary_course_'.$course->getCode(), true);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Export::arrayToXl...ourse->getCode(), true) could return the type false which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
121
    }
122
123
    private function generatePdfFile(array $glossaryItems, Course $course): string
124
    {
125
        $html = '<h1>'.$this->translator->trans('Glossary').'</h1>';
126
        $html .= '<table>';
127
        $html .= '<tr><th>'.$this->translator->trans('Term').'</th><th>'.$this->translator->trans('Term definition').'</th></tr>';
128
129
        /** @var CGlossary $item */
130
        foreach ($glossaryItems as $item) {
131
            $html .= '<tr>';
132
            $html .= '<td>'.$item->getTitle().'</td>';
133
            $html .= '<td>'.$item->getDescription().'</td>';
134
            $html .= '</tr>';
135
        }
136
        $html .= '</table>';
137
138
        return (new PDF())
139
            ->content_to_pdf(
140
                $html,
141
                null,
142
                get_lang('Glossary').'_'.$course->getCode(),
143
                $course->getCode(),
144
                'F',
145
                false,
146
                null,
147
                false,
148
                true
149
            );
150
    }
151
}
152