Completed
Push — master ( 555010...ab7f11 )
by Torben
04:40 queued 03:06
created

ExportService::hasWriteAccessToTempFolder()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 1
Bugs 1 Features 0
Metric Value
dl 0
loc 20
ccs 9
cts 9
cp 1
rs 9.2
c 1
b 1
f 0
cc 4
eloc 12
nc 5
nop 0
crap 4
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\Registration;
12
use DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository;
13
use DERHANSEN\SfEventMgt\Exception;
14
use TYPO3\CMS\Core\Resource\Folder;
15
use TYPO3\CMS\Core\Resource\ResourceFactory;
16
use TYPO3\CMS\Core\Utility\GeneralUtility;
17
18
/**
19
 * Class ExportService
20
 *
21
 * @author Torben Hansen <[email protected]>
22
 */
23
class ExportService
24
{
25
    /**
26
     * Repository with registrations for the events
27
     *
28
     * @var \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository
29
     */
30
    protected $registrationRepository;
31
32
    /**
33
     * ResourceFactory
34
     *
35
     * @var \TYPO3\CMS\Core\Resource\ResourceFactory
36
     */
37
    protected $resourceFactory = null;
38
39
    /**
40
     * DI for $registrationRepository
41
     *
42
     * @param RegistrationRepository $registrationRepository
43
     */
44
    public function injectRegistrationRepository(
45
        \DERHANSEN\SfEventMgt\Domain\Repository\RegistrationRepository $registrationRepository
46
    ) {
47
        $this->registrationRepository = $registrationRepository;
48
    }
49
50
    /**
51
     * DI for $resourceFactory
52
     *
53 4
     * @param ResourceFactory $resourceFactory
54
     */
55 4
    public function injectResourceFactory(\TYPO3\CMS\Core\Resource\ResourceFactory $resourceFactory)
56 4
    {
57 2
        $this->resourceFactory = $resourceFactory;
58
    }
59 2
60 2
    /**
61 2
     * Initiates the CSV downloads for registrations of the given event uid
62 2
     *
63 2
     * @param int $eventUid EventUid
64 2
     * @param array $settings Settings
65 2
     * @throws Exception RuntimeException
66
     * @return void
67
     */
68
    public function downloadRegistrationsCsv($eventUid, $settings = [])
69
    {
70
        $storage = $this->resourceFactory->getDefaultStorage();
71
        if ($storage === null) {
72
            throw new Exception('Could not get the default storage', 1475590001);
73
        }
74
        $registrations = $this->exportRegistrationsCsv($eventUid, $settings);
75
        $tempFolder = $storage->getFolder('_temp_');
76 10
        $tempFile = $storage->createFile('sf_events_export.csv', $tempFolder);
77
        $tempFile->setContents($registrations);
78 10
        $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 76 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...
79 10
        $tempFile->delete();
80 10
    }
81 10
82 10
    /**
83 10
     * Returns, if the user has read/write access permissions to the __temp__ folder
84 10
     *
85 10
     * @return bool
86 10
     */
87 10
    public function hasWriteAccessToTempFolder()
88 2
    {
89 2
        $result = true;
90
        $storage = $this->resourceFactory->getDefaultStorage();
91 10
        if ($storage === null) {
92 8
            return false;
93 8
        }
94 8
95 8
        try {
96
            /** @var Folder $folder */
97
            $folder = $storage->getFolder('_temp_');
98
            if (!$folder->checkActionPermission('write')) {
99
                $result = false;
100
            }
101
        } catch (\Exception $e) {
102
            $result = false;
103
        }
104
105
        return $result;
106 10
    }
107
108 10
    /**
109 10
     * Returns all Registrations for the given eventUid as a CSV string
110
     *
111
     * @param int $eventUid EventUid
112 10
     * @param array $settings Settings
113
     * @throws Exception RuntimeException
114
     * @return string
115
     */
116
    public function exportRegistrationsCsv($eventUid, $settings = [])
117
    {
118
        $fieldsArray = array_map('trim', explode(',', $settings['fields']));
119
        $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...
120
        $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...
121
            $fieldsArray,
122
            $settings['fieldDelimiter'],
123
            $settings['fieldQuoteCharacter']
124
        ) . chr(10);
125
        /** @var Registration $registration */
126
        foreach ($registrations as $registration) {
127
            $exportedRegistration = [];
128
            foreach ($fieldsArray as $field) {
129
                if ($registration->_hasProperty($field)) {
130
                    $exportedRegistration[] = $this->getFieldValue($registration, $field);
131
                } else {
132
                    throw new Exception('Field ' . $field .
133
                        ' is not a Property of Model Registration, please check your TS configuration', 1475590002);
134
                }
135
            }
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
                $exportedRegistration,
138
                $settings['fieldDelimiter'],
139
                $settings['fieldQuoteCharacter']
140
            ) . chr(10);
141
        }
142
143
        return $this->prependByteOrderMark($exportedRegistrations, $settings);
144
    }
145
146
    /**
147
     * Prepends Byte Order Mark to exported registrations
148
     *
149
     * @param string $exportedRegistrations
150
     * @param array $settings
151
     * @return string
152
     */
153
    protected function prependByteOrderMark($exportedRegistrations, $settings)
154
    {
155
        if ((bool)$settings['prependBOM']) {
156
            $exportedRegistrations = chr(239) . chr(187) . chr(191) . $exportedRegistrations;
157
        }
158
159
        return $exportedRegistrations;
160
    }
161
162
    /**
163
     * Returns the requested field from the given registration. If the field is a DateTime object,
164
     * a formatted date string is returned
165
     *
166
     * @param \DERHANSEN\SfEventMgt\Domain\Model\Registration $registration
167
     * @param string $field
168
     * @return string
169
     */
170
    protected function getFieldValue($registration, $field)
171
    {
172
        $value = $registration->_getCleanProperty($field);
173
        if ($value instanceof \DateTime) {
174
            $value = $value->format('d.m.Y');
175
        }
176
177
        return $value;
178
    }
179
}
180