Passed
Push — 6.x ( 91d5aa...146492 )
by Torben
17:15 queued 09:02
created

ExportService::getBackendUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Extension "sf_event_mgt" for TYPO3 CMS.
7
 *
8
 * For the full copyright and license information, please read the
9
 * LICENSE.txt file that was distributed with this source code.
10
 */
11
12
namespace DERHANSEN\SfEventMgt\Service;
13
14
use DERHANSEN\SfEventMgt\Domain\Model\Event;
15
use DERHANSEN\SfEventMgt\Domain\Model\Registration;
16
use DERHANSEN\SfEventMgt\Domain\Model\Registration\Field;
17
use DERHANSEN\SfEventMgt\Domain\Repository\EventRepository;
18
use DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository;
19
use DERHANSEN\SfEventMgt\Exception;
20
use TYPO3\CMS\Core\Utility\CsvUtility;
21
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
22
23
/**
24
 * Class ExportService
25
 */
26
class ExportService
27
{
28
    protected RegistrationRepository $registrationRepository;
29
    protected EventRepository $eventRepository;
30
31
    public function __construct(RegistrationRepository $registrationRepository, EventRepository $eventRepository)
32
    {
33
        $this->registrationRepository = $registrationRepository;
34
        $this->eventRepository = $eventRepository;
35
    }
36
37
    /**
38
     * Initiates the CSV downloads for registrations of the given event uid
39
     *
40
     * @throws Exception RuntimeException
41
     */
42
    public function downloadRegistrationsCsv(int $eventUid, array $settings = []): void
43
    {
44
        $content = $this->exportRegistrationsCsv($eventUid, $settings);
45
        header('Content-Disposition: attachment; filename="event_' . $eventUid . '_reg_' . date('dmY_His') . '.csv"');
46
        header('Content-Type: text/csv');
47
        header('Content-Length: ' . strlen($content));
48
        header('Expires: 0');
49
        header('Cache-Control: must-revalidate');
50
        header('Pragma: no-cache');
51
        echo $content;
52
    }
53
54
    /**
55
     * Returns all Registrations for the given eventUid as a CSV string
56
     *
57
     * @throws Exception RuntimeException
58
     */
59
    public function exportRegistrationsCsv(int $eventUid, array $settings = []): string
60
    {
61
        $hasRegistrationFields = false;
62
        $registrationFieldData = [];
63
        $fieldsArray = array_map('trim', explode(',', ($settings['fields'] ?? '')));
64
65
        if (in_array('registration_fields', $fieldsArray)) {
66
            $hasRegistrationFields = true;
67
            $registrationFieldData = $this->getRegistrationFieldData($eventUid);
68
            $fieldsArray = array_diff($fieldsArray, ['registration_fields']);
69
        }
70
        $registrations = $this->registrationRepository->findByEvent($eventUid);
0 ignored issues
show
Bug introduced by
The method findByEvent() does not exist on DERHANSEN\SfEventMgt\Dom...\RegistrationRepository. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

70
        /** @scrutinizer ignore-call */ 
71
        $registrations = $this->registrationRepository->findByEvent($eventUid);
Loading history...
71
        $exportedRegistrations = CsvUtility::csvValues(
72
            array_merge($fieldsArray, $registrationFieldData),
73
            $settings['fieldDelimiter'] ?? ',',
74
            $settings['fieldQuoteCharacter'] ?? '"'
75
        ) . chr(10);
76
        /** @var Registration $registration */
77
        foreach ($registrations as $registration) {
78
            $exportedRegistration = [];
79
            foreach ($fieldsArray as $field) {
80
                $exportedRegistration[] = $this->getFieldValue($registration, $field, $settings);
81
            }
82
            if ($hasRegistrationFields) {
83
                $exportedRegistration = array_merge(
84
                    $exportedRegistration,
85
                    $this->getRegistrationFieldValues($registration, $registrationFieldData)
86
                );
87
            }
88
            $exportedRegistrations .= CsvUtility::csvValues(
89
                $exportedRegistration,
90
                $settings['fieldDelimiter'] ?? ',',
91
                $settings['fieldQuoteCharacter'] ?? '"'
92
            ) . chr(10);
93
        }
94
95
        return $this->prependByteOrderMark($exportedRegistrations, $settings);
96
    }
97
98
    /**
99
     * Returns an array with fieldvalues for the given registration
100
     */
101
    protected function getRegistrationFieldValues(Registration $registration, array $registrationFieldData): array
102
    {
103
        $result = [];
104
        $registrationFieldValues = [];
105
        /** @var Registration\FieldValue $fieldValue */
106
        foreach ($registration->getFieldValues() as $fieldValue) {
107
            $field = $fieldValue->getField();
108
            if ($field !== null) {
109
                $registrationFieldValues[$field->getUid()] =
110
                    $this->replaceLineBreaks($fieldValue->getValueForCsvExport());
111
            }
112
        }
113
        foreach ($registrationFieldData as $fieldUid => $fieldTitle) {
114
            if (isset($registrationFieldValues[$fieldUid])) {
115
                $result[] = $registrationFieldValues[$fieldUid];
116
            } else {
117
                $result[] = '';
118
            }
119
        }
120
121
        return $result;
122
    }
123
124
    /**
125
     * Returns an array of registration field uids and title
126
     */
127
    protected function getRegistrationFieldData(int $eventUid): array
128
    {
129
        $result = [];
130
        /** @var Event $event */
131
        $event = $this->eventRepository->findByUid($eventUid);
132
        if ($event !== null) {
133
            $result = $event->getRegistrationFieldUidsWithTitle();
134
        }
135
136
        return $result;
137
    }
138
139
    /**
140
     * Prepends Byte Order Mark to exported registrations
141
     */
142
    protected function prependByteOrderMark(string $exportedRegistrations, array $settings): string
143
    {
144
        if ((bool)($settings['prependBOM'] ??  false)) {
145
            $exportedRegistrations = chr(239) . chr(187) . chr(191) . $exportedRegistrations;
146
        }
147
148
        return $exportedRegistrations;
149
    }
150
151
    /**
152
     * Returns the requested field from the given registration. If the field is a DateTime object,
153
     * a formatted date string is returned
154
     */
155
    protected function getFieldValue(Registration $registration, string $field, array $settings): string
156
    {
157
        $value = ObjectAccess::getPropertyPath($registration, $field);
158
        if ($value instanceof \DateTime) {
159
            $dateFormat = $settings['dateFieldFormat'] ?? 'd.m.Y';
160
            $value = $value->format($dateFormat);
161
        }
162
163
        return $this->replaceLineBreaks($value);
164
    }
165
166
    /**
167
     * Replaces all line breaks with a space
168
     *
169
     * @param mixed $value
170
     * @return mixed
171
     */
172
    protected function replaceLineBreaks($value)
173
    {
174
        return str_replace(["\r\n", "\r", "\n"], ' ', (string)$value);
175
    }
176
}
177