Completed
Push — development ( 9d105e...bf3399 )
by Torben
04:26
created

ExportService::injectEventRepository()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
namespace DERHANSEN\SfEventMgt\Service;
3
4
/*
5
 * This file is part of the Extension "sf_event_mgt" for TYPO3 CMS.
6
 *
7
 * For the full copyright and license information, please read the
8
 * LICENSE.txt file that was distributed with this source code.
9
 */
10
11
use DERHANSEN\SfEventMgt\Domain\Model\Event;
12
use DERHANSEN\SfEventMgt\Domain\Model\Registration;
13
use DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository;
14
use DERHANSEN\SfEventMgt\Exception;
15
use TYPO3\CMS\Core\Resource\Folder;
16
use TYPO3\CMS\Core\Resource\ResourceFactory;
17
use TYPO3\CMS\Core\Utility\GeneralUtility;
18
19
/**
20
 * Class ExportService
21
 *
22
 * @author Torben Hansen <[email protected]>
23
 */
24
class ExportService
25
{
26
    /**
27
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository
28
     */
29
    protected $registrationRepository = null;
30
31
    /**
32
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\EventRepository
33
     */
34
    protected $eventRepository = null;
35
36
    /**
37
     * ResourceFactory
38
     *
39
     * @var \TYPO3\CMS\Core\Resource\ResourceFactory
40
     */
41
    protected $resourceFactory = null;
42
43
    /**
44
     * @param RegistrationRepository $registrationRepository
45
     */
46
    public function injectRegistrationRepository(
47
        \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository $registrationRepository
48
    ) {
49
        $this->registrationRepository = $registrationRepository;
50
    }
51
52
    /**
53 2
     * @param \DERHANSEN\SfEventMgt\Domain\Repository\EventRepository $eventRepository
54
     */
55 2
    public function injectEventRepository(\DERHANSEN\SfEventMgt\Domain\Repository\EventRepository $eventRepository)
56 2
    {
57 1
        $this->eventRepository = $eventRepository;
58
    }
59 1
60 1
    /**
61 1
     * @param ResourceFactory $resourceFactory
62 1
     */
63 1
    public function injectResourceFactory(\TYPO3\CMS\Core\Resource\ResourceFactory $resourceFactory)
64 1
    {
65 1
        $this->resourceFactory = $resourceFactory;
66
    }
67
68
    /**
69
     * Initiates the CSV downloads for registrations of the given event uid
70
     *
71
     * @param int $eventUid EventUid
72
     * @param array $settings Settings
73
     * @throws Exception RuntimeException
74
     * @return void
75
     */
76 5
    public function downloadRegistrationsCsv($eventUid, $settings = [])
77
    {
78 5
        $storage = $this->resourceFactory->getDefaultStorage();
79 5
        if ($storage === null) {
80 5
            throw new Exception('Could not get the default storage', 1475590001);
81 5
        }
82 5
        $registrations = $this->exportRegistrationsCsv($eventUid, $settings);
83 5
        $tempFolder = $storage->getFolder('_temp_');
84 5
        $tempFile = $storage->createFile('sf_events_export.csv', $tempFolder);
85 5
        $tempFile->setContents($registrations);
86 5
        $storage->dumpFileContents($tempFile, true, 'registrations_' . date('dmY_His') . '.csv');
0 ignored issues
show
Bug introduced by
It seems like $tempFile defined by $storage->createFile('sf...port.csv', $tempFolder) on line 84 can also be of type null; however, TYPO3\CMS\Core\Resource\...age::dumpFileContents() does only seem to accept object<TYPO3\CMS\Core\Resource\FileInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
87 5
        $tempFile->delete();
88 1
    }
89 1
90
    /**
91 5
     * Returns, if the user has read/write access permissions to the __temp__ folder
92 4
     *
93 4
     * @return bool
94 4
     */
95 4
    public function hasWriteAccessToTempFolder()
96
    {
97
        $result = true;
98
        $storage = $this->resourceFactory->getDefaultStorage();
99
        if ($storage === null) {
100
            return false;
101
        }
102
103
        try {
104
            /** @var Folder $folder */
105
            $folder = $storage->getFolder('_temp_');
106 5
            if (!$folder->checkActionPermission('write')) {
107
                $result = false;
108 5
            }
109 5
        } catch (\Exception $e) {
110
            $result = false;
111
        }
112 5
113
        return $result;
114
    }
115
116
    /**
117
     * Returns all Registrations for the given eventUid as a CSV string
118
     *
119
     * @param int $eventUid EventUid
120
     * @param array $settings Settings
121
     * @throws Exception RuntimeException
122
     * @return string
123
     */
124
    public function exportRegistrationsCsv($eventUid, $settings = [])
125
    {
126
        $hasRegistrationFields = false;
127
        $registrationFieldData = [];
128
        $fieldsArray = array_map('trim', explode(',', $settings['fields']));
129
130
        if (in_array('registration_fields', $fieldsArray)) {
131
            $hasRegistrationFields = true;
132
            $registrationFieldData = $this->getRegistrationFieldData($eventUid);
133
            $fieldsArray = array_diff($fieldsArray, ['registration_fields']);
134
        }
135
        $registrations = $this->registrationRepository->findByEvent($eventUid);
0 ignored issues
show
Documentation Bug introduced by
The method findByEvent does not exist on object<DERHANSEN\SfEvent...RegistrationRepository>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
136
        $exportedRegistrations = GeneralUtility::csvValues(
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Core\Utility\GeneralUtility::csvValues() has been deprecated with message: since TYPO3 v8, will be removed in TYPO3 v9.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
137
            array_merge($fieldsArray, $registrationFieldData),
138
            $settings['fieldDelimiter'],
139
            $settings['fieldQuoteCharacter']
140
        ) . chr(10);
141
        /** @var Registration $registration */
142
        foreach ($registrations as $registration) {
143
            $exportedRegistration = [];
144
            foreach ($fieldsArray as $field) {
145
                if ($registration->_hasProperty($field)) {
146
                    $exportedRegistration[] = $this->getFieldValue($registration, $field);
147
                } else {
148
                    throw new Exception('Field ' . $field .
149
                        ' is not a Property of Model Registration, please check your TS configuration', 1475590002);
150
                }
151
            }
152
            if ($hasRegistrationFields) {
153
                $exportedRegistration = array_merge(
154
                    $exportedRegistration,
155
                    $this->getRegistrationFieldValues($registration, $registrationFieldData)
156
                );
157
            }
158
            $exportedRegistrations .= GeneralUtility::csvValues(
0 ignored issues
show
Deprecated Code introduced by
The method TYPO3\CMS\Core\Utility\GeneralUtility::csvValues() has been deprecated with message: since TYPO3 v8, will be removed in TYPO3 v9.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
159
                $exportedRegistration,
160
                $settings['fieldDelimiter'],
161
                $settings['fieldQuoteCharacter']
162
            ) . chr(10);
163
        }
164
165
        return $this->prependByteOrderMark($exportedRegistrations, $settings);
166
    }
167
168
    /**
169
     * Returns an array with fieldvalues for the given registration
170
     *
171
     * @param Registration $registration
172
     * @param array $registrationFieldData
173
     * @return array
174
     */
175
    protected function getRegistrationFieldValues($registration, $registrationFieldData)
176
    {
177
        $result = [];
178
        $registrationFieldValues = [];
179
        /** @var Registration\FieldValue $fieldValue */
180
        foreach ($registration->getFieldValues() as $fieldValue) {
181
            $registrationFieldValues[$fieldValue->getField()->getUid()] = $fieldValue->getValueForCsvExport();
182
        }
183
        foreach ($registrationFieldData as $fieldUid => $fieldTitle) {
184
            if (isset($registrationFieldValues[$fieldUid])) {
185
                $result[] = $registrationFieldValues[$fieldUid];
186
            } else {
187
                $result[] = '';
188
            }
189
        }
190
        return $result;
191
    }
192
193
    /**
194
     * Returns an array of registration field uids and title
195
     *
196
     * @param int $eventUid
197
     * @return array
198
     */
199
    protected function getRegistrationFieldData($eventUid)
200
    {
201
        $result = [];
202
        /** @var Event $event */
203
        $event = $this->eventRepository->findByUid($eventUid);
204
        if ($event) {
205
            $result = $event->getRegistrationFieldUidsWithTitle();
206
        }
207
        return $result;
208
    }
209
210
    /**
211
     * Prepends Byte Order Mark to exported registrations
212
     *
213
     * @param string $exportedRegistrations
214
     * @param array $settings
215
     * @return string
216
     */
217
    protected function prependByteOrderMark($exportedRegistrations, $settings)
218
    {
219
        if ((bool)$settings['prependBOM']) {
220
            $exportedRegistrations = chr(239) . chr(187) . chr(191) . $exportedRegistrations;
221
        }
222
223
        return $exportedRegistrations;
224
    }
225
226
    /**
227
     * Returns the requested field from the given registration. If the field is a DateTime object,
228
     * a formatted date string is returned
229
     *
230
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
231
     * @param string $field
232
     * @return string
233
     */
234
    protected function getFieldValue($registration, $field)
235
    {
236
        $value = $registration->_getCleanProperty($field);
237
        if ($value instanceof \DateTime) {
238
            $value = $value->format('d.m.Y');
239
        }
240
241
        return $value;
242
    }
243
}
244