OverwriteProtectionService   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 241
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 98.96%

Importance

Changes 0
Metric Value
wmc 32
lcom 1
cbo 6
dl 0
loc 241
ccs 95
cts 96
cp 0.9896
rs 9.84
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A processCmdmap_postProcess() 0 10 3
B processDatamap_preProcessFieldArray() 0 52 7
B processDatamap_afterDatabaseOperations() 0 41 10
A hasOverWriteProtection() 0 10 4
A needsOverWriteProtection() 0 7 3
A removeOverwriteProtection() 0 9 2
A convertClientTimestampToUTC() 0 12 2
1
<?php
2
namespace Aoe\AoeDbSequenzer\Service;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2017 AOE GmbH ([email protected])
8
 *  All rights reserved
9
 *
10
 *  This script is part of the TYPO3 project. The TYPO3 project is
11
 *  free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 2 of the License, or
14
 *  (at your option) any later version.
15
 *
16
 *  The GNU General Public License can be found at
17
 *  http://www.gnu.org/copyleft/gpl.html.
18
 *
19
 *  This script is distributed in the hope that it will be useful,
20
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 *  GNU General Public License for more details.
23
 *
24
 *  This copyright notice MUST APPEAR in all copies of the script!
25
 ***************************************************************/
26
27
use Aoe\AoeDbSequenzer\Domain\Model\OverwriteProtection;
28
use Aoe\AoeDbSequenzer\Domain\Repository\OverwriteProtectionRepository;
29
use TYPO3\CMS\Core\DataHandling\DataHandler;
30
use TYPO3\CMS\Core\Utility\GeneralUtility;
31
use TYPO3\CMS\Extbase\Object\ObjectManager;
32
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
33
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
34
35
/**
36
 * @package Aoe\AoeDbSequenzer
37
 */
38
class OverwriteProtectionService
39
{
40
    /**
41
     * @var string
42
     */
43
    const OVERWRITE_PROTECTION_TABLE = 'tx_aoedbsequenzer_domain_model_overwriteprotection';
44
45
    /**
46
     * @var string
47
     */
48
    const OVERWRITE_PROTECTION_TILL = 'tx_aoe_dbsquenzer_protectoverwrite_till';
49
50
    /**
51
     * @var string
52
     */
53
    const OVERWRITE_PROTECTION_MODE = 'tx_aoe_dbsquenzer_protectoverwrite_mode';
54
55
    /**
56
     * array of configured tables that should call the sequenzer
57
     *
58
     * @var array
59
     */
60
    private $supportedTables;
61
62
    /**
63
     * @var OverwriteProtectionRepository
64
     */
65
    private $overwriteProtectionRepository;
66
67
    /**
68
     * @var PersistenceManager
69
     */
70
    private $persistenceManager;
71
72
    /**
73
     * @var ObjectManagerInterface
74
     */
75
    private $objectManager;
76
77 14
    public function __construct()
78
    {
79 14
        $extConf = unserialize($GLOBALS ['TYPO3_CONF_VARS'] ['EXT'] ['extConf'] ['aoe_dbsequenzer']);
80 14
        $explodedValues = explode(',', $extConf ['tables']);
81 14
        $this->supportedTables = array_map('trim', $explodedValues);
82
83 14
        $this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
84 14
        $this->overwriteProtectionRepository = $this->objectManager->get(OverwriteProtectionRepository::class);
85 14
        $this->persistenceManager = $this->objectManager->get(PersistenceManager::class);
86 14
    }
87
88
    /**
89
     * Hook for deletes in Typo3 Backend. It also delete all overwrite protection
90
     * @param string $command
91
     * @param string $table
92
     * @param integer $id
93
     */
94 3
    public function processCmdmap_postProcess($command, $table, $id)
95
    {
96 3
        if (false === $this->needsOverWriteProtection($table)) {
97 1
            return;
98
        }
99 2
        if ($command !== 'delete') {
100 1
            return;
101
        }
102 1
        $this->removeOverwriteProtection($id, $table);
103 1
    }
104
105
    /**
106
     * Hook for updates in Typo3 backend
107
     * @param array $incomingFieldArray
108
     * @param string $table
109
     * @param integer $id
110
     * @param DataHandler $dataHandler
111
     */
112 6
    public function processDatamap_preProcessFieldArray(&$incomingFieldArray, $table, $id, DataHandler &$dataHandler)
113
    {
114 6
        if (false === $this->needsOverWriteProtection($table)) {
115 1
            return;
116
        }
117
118
        // check, if overwrite-protection-fields are set:
119
        // If they are NOT set, it means, that any other extension maybe called the process_datamap!
120 5
        if (false === array_key_exists(self::OVERWRITE_PROTECTION_TILL, $incomingFieldArray) ||
121 5
            false === array_key_exists(self::OVERWRITE_PROTECTION_MODE, $incomingFieldArray)
122
        ) {
123 1
            return;
124
        }
125
126
        // Only handle overwrite protection if database record is not new
127 4
        if (GeneralUtility::isFirstPartOfStr($id, 'NEW')) {
128 1
            unset($incomingFieldArray [self::OVERWRITE_PROTECTION_TILL]);
129 1
            unset($incomingFieldArray [self::OVERWRITE_PROTECTION_MODE]);
130 1
            return;
131
        }
132
133 3
        if (false === $this->hasOverWriteProtection($incomingFieldArray)) {
134 1
            $this->removeOverwriteProtection($id, $table);
135
        } else {
136 2
            $protectionTime = $incomingFieldArray [self::OVERWRITE_PROTECTION_TILL];
137 2
            $mode = $incomingFieldArray [self::OVERWRITE_PROTECTION_MODE];
138
139 2
            $protectionTime = $this->convertClientTimestampToUTC($protectionTime, $table, $dataHandler);
140
141 2
            $queryResult = $this->overwriteProtectionRepository->findByProtectedUidAndTableName($id, $table);
142 2
            if ($queryResult->count() === 0) {
143
                /* @var $overwriteProtection OverwriteProtection */
144 1
                $overwriteProtection = $this->objectManager->get(OverwriteProtection::class);
145 1
                $overwriteProtection->setProtectedMode($mode);
146 1
                $overwriteProtection->setPid($dataHandler->getPID($table, $id));
0 ignored issues
show
Security Bug introduced by
It seems like $dataHandler->getPID($table, $id) targeting TYPO3\CMS\Core\DataHandling\DataHandler::getPID() can also be of type false; however, TYPO3\CMS\Extbase\Domain...tDomainObject::setPid() does only seem to accept integer|null, did you maybe forget to handle an error condition?
Loading history...
147 1
                $overwriteProtection->setProtectedTablename($table);
148 1
                $overwriteProtection->setProtectedUid($id);
149 1
                $overwriteProtection->setProtectedTime($protectionTime);
150 1
                $this->overwriteProtectionRepository->add($overwriteProtection);
151
            } else {
152
                /* @var $overwriteProtection OverwriteProtection */
153 1
                $overwriteProtection = $queryResult->getFirst();
154 1
                $overwriteProtection->setProtectedMode($mode);
155 1
                $overwriteProtection->setProtectedTime($protectionTime);
156 1
                $this->overwriteProtectionRepository->update($overwriteProtection);
157
            }
158 2
            $this->persistenceManager->persistAll();
159
        }
160
161 3
        unset($incomingFieldArray [self::OVERWRITE_PROTECTION_TILL]);
162 3
        unset($incomingFieldArray [self::OVERWRITE_PROTECTION_MODE]);
163 3
    }
164
165
    /**
166
     * @param string $status Status "new" or "update"
167
     * @param string $table Table name
168
     * @param string $id Record ID. If new record its a string pointing to index inside \TYPO3\CMS\Core\DataHandling\DataHandler::substNEWwithIDs
169
     * @param array $fieldArray Field array of updated fields in the operation
170
     * @param DataHandler $dataHandler tcemain calling object
171
     * @return void
172
     */
173 5
    public function processDatamap_afterDatabaseOperations($status, $table, $id, $fieldArray, $dataHandler)
0 ignored issues
show
Unused Code introduced by
The parameter $fieldArray is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
174
    {
175
        // check basic pre-conditions - only handle new database record
176 5
        if ($status !== 'new' ||
177 4
            false === GeneralUtility::isFirstPartOfStr($id, 'NEW') ||
178 5
            false === $this->needsOverWriteProtection($table)
179
        ) {
180 2
            return;
181
        }
182
183
        // check if all required dataHandler fields are available
184 3
        if (!isset($dataHandler->datamap[$table]) ||
185 3
            !isset($dataHandler->datamap[$table][$id]) ||
186 3
            !isset($dataHandler->datamap[$table][$id][self::OVERWRITE_PROTECTION_TILL]) ||
187 2
            !isset($dataHandler->datamap[$table][$id][self::OVERWRITE_PROTECTION_MODE]) ||
188 3
            !isset($dataHandler->substNEWwithIDs[$id])
189
        ) {
190 2
            return;
191
        }
192
193
        // check if overwrite protection fields are filled
194 1
        if (false === $this->hasOverWriteProtection($dataHandler->datamap[$table][$id])) {
195
            return;
196
        }
197
198 1
        $uid = $dataHandler->substNEWwithIDs[$id];
199 1
        $protectionTime = $dataHandler->datamap[$table][$id][self::OVERWRITE_PROTECTION_TILL];
200 1
        $mode = $dataHandler->datamap[$table][$id][self::OVERWRITE_PROTECTION_MODE];
201
202 1
        $protectionTime = $this->convertClientTimestampToUTC($protectionTime, $table, $dataHandler);
203
204 1
        $overwriteProtection = $this->objectManager->get(OverwriteProtection::class);
205 1
        $overwriteProtection->setProtectedMode($mode);
206 1
        $overwriteProtection->setPid($dataHandler->getPID($table, $uid));
207 1
        $overwriteProtection->setProtectedTablename($table);
208 1
        $overwriteProtection->setProtectedUid($uid);
209 1
        $overwriteProtection->setProtectedTime($protectionTime);
210
211 1
        $this->overwriteProtectionRepository->add($overwriteProtection);
212 1
        $this->persistenceManager->persistAll();
213 1
    }
214
215
    /**
216
     * @param array $fields_values
217
     * @return boolean
218
     */
219 4
    private function hasOverWriteProtection(array $fields_values)
220
    {
221 4
        if (isset ($fields_values [self::OVERWRITE_PROTECTION_TILL])) {
222 4
            $value = trim($fields_values [self::OVERWRITE_PROTECTION_TILL]);
223 4
            if (false === empty ($value) && false !== is_numeric($value)) {
224 3
                return true;
225
            }
226
        }
227 1
        return false;
228
    }
229
230
    /**
231
     * If a table is configured to use the sequenzer
232
     *
233
     * @param string $tableName
234
     * @return boolean
235
     */
236 13
    private function needsOverWriteProtection($tableName)
237
    {
238 13
        if ($tableName !== self::OVERWRITE_PROTECTION_TABLE && in_array($tableName, $this->supportedTables)) {
239 10
            return true;
240
        }
241 3
        return false;
242
    }
243
244
    /**
245
     * remove overwriteProtection
246
     *
247
     * @param integer $id
248
     * @param string $table
249
     */
250 2
    private function removeOverwriteProtection($id, $table)
251
    {
252 2
        $queryResult = $this->overwriteProtectionRepository->findByProtectedUidAndTableName($id, $table);
253 2
        if ($queryResult->count() > 0) {
254 2
            $overwriteProtection = $queryResult->getFirst();
255 2
            $this->overwriteProtectionRepository->remove($overwriteProtection);
256 2
            $this->persistenceManager->persistAll();
257
        }
258 2
    }
259
260
    /**
261
     * @param string $dateTimeValue
262
     * @param string $table
263
     * @param DataHandler $dataHandler
264
     * @return string
265
     */
266 3
    private function convertClientTimestampToUTC($dateTimeValue, $table, DataHandler $dataHandler)
267
    {
268 3
        $evalArray = explode(',', $GLOBALS['TCA'][$table]['columns'][self::OVERWRITE_PROTECTION_TILL]['config']['eval']);
269
270 3
        $evalResult = $dataHandler->checkValue_input_Eval($dateTimeValue, $evalArray, null);
271
272 3
        if (isset($evalResult['value'])) {
273 2
            return $evalResult['value'];
274
        }
275
276 1
        return $dateTimeValue;
277
    }
278
}
279