Passed
Push — refactoring/typo3v10 ( fa15e2...b994b5 )
by Felix
21:19
created

TCA::renderSelectForFlag()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 14
nc 3
nop 1
dl 0
loc 22
ccs 0
cts 19
cp 0
crap 20
rs 9.7998
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A TCA::processDatamap_preProcessFieldArray() 0 15 3
1
<?php
2
namespace Aoe\FeatureFlag\System\Typo3;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2021 AOE GmbH <[email protected]>
8
 *
9
 *  All rights reserved
10
 *
11
 *  This script is part of the TYPO3 project. The TYPO3 project is
12
 *  free software; you can redistribute it and/or modify
13
 *  it under the terms of the GNU General Public License as published by
14
 *  the Free Software Foundation; either version 3 of the License, or
15
 *  (at your option) any later version.
16
 *
17
 *  The GNU General Public License can be found at
18
 *  http://www.gnu.org/copyleft/gpl.html.
19
 *
20
 *  This script is distributed in the hope that it will be useful,
21
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 *  GNU General Public License for more details.
24
 *
25
 *  This copyright notice MUST APPEAR in all copies of the script!
26
 ***************************************************************/
27
28
use Aoe\FeatureFlag\Domain\Model\FeatureFlag;
29
use Aoe\FeatureFlag\Domain\Model\Mapping;
30
use Aoe\FeatureFlag\Domain\Repository\FeatureFlagRepository;
31
use Aoe\FeatureFlag\Domain\Repository\MappingRepository;
32
use Aoe\FeatureFlag\Service\Exception\FeatureNotFoundException;
33
use TYPO3\CMS\Core\DataHandling\DataHandler;
34
use TYPO3\CMS\Core\Localization\LanguageService;
35
use TYPO3\CMS\Core\Utility\GeneralUtility;
36
use TYPO3\CMS\Extbase\Object\ObjectManager;
37
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
38
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
39
40
class TCA
41
{
42
    /**
43
     * @var string
44
     */
45
    const FIELD_BEHAVIOR = 'tx_featureflag_behavior';
46
47
    /**
48
     * @var string
49
     */
50
    const FIELD_FLAG = 'tx_featureflag_flag';
51
52
    /**
53
     * @var ObjectManager
54
     */
55
    protected $objectManager;
56
57
    /**
58
     * @var PersistenceManager
59
     */
60
    protected $persistenceManager;
61
62
    /**
63
     * @var QueryResultInterface
64
     */
65
    protected static $hashedMappings;
66
67
    /**
68
     * Hook for updates in Typo3 backend
69
     * @param array $incomingFieldArray
70
     * @param string $table
71
     * @param integer $id
72
     * @param DataHandler $dataHandler
73
     * @codingStandardsIgnoreStart
74
     */
75
    public function processDatamap_preProcessFieldArray(
76
        &$incomingFieldArray,
77
        $table,
78
        $id,
79
        DataHandler $dataHandler
80
    ) {
81
        // @codingStandardsIgnoreEnd
82
        if (
83
            array_key_exists(self::FIELD_BEHAVIOR, $incomingFieldArray) &&
84
            array_key_exists(self::FIELD_FLAG, $incomingFieldArray)
85
        ) {
86
            $pid = $dataHandler->getPID($table, $id);
87
            $this->updateMapping($table, $id, $incomingFieldArray[self::FIELD_FLAG], $pid, $incomingFieldArray[self::FIELD_BEHAVIOR]);
0 ignored issues
show
Bug introduced by
It seems like $pid can also be of type false; however, parameter $pid of Aoe\FeatureFlag\System\Typo3\TCA::updateMapping() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

87
            $this->updateMapping($table, $id, $incomingFieldArray[self::FIELD_FLAG], /** @scrutinizer ignore-type */ $pid, $incomingFieldArray[self::FIELD_BEHAVIOR]);
Loading history...
88
            unset($incomingFieldArray[self::FIELD_BEHAVIOR]);
89
            unset($incomingFieldArray[self::FIELD_FLAG]);
90
        }
91
    }
92
93
    /**
94
     * Hook for deletes in Typo3 Backend. It also delete all overwrite protection
95
     * @param string $command
96
     * @param string $table
97
     * @param integer $id
98
     * @codingStandardsIgnoreStart
99
     */
100
    public function processCmdmap_postProcess($command, $table, $id)
101
    {
102
        // @codingStandardsIgnoreEnd
103
        if ($command !== 'delete') {
104
            return;
105
        }
106
        $mappings = $this->getMappingRepository()->findAllByForeignTableNameAndUid($id, $table);
107
        if (false === is_array($mappings) && false === ($mappings instanceof QueryResultInterface)) {
108
            return;
109
        }
110
        foreach ($mappings as $mapping) {
111
            if ($mapping instanceof Mapping) {
112
                $this->getMappingRepository()->remove($mapping);
113
            }
114
        }
115
        $this->getPersistenceManager()->persistAll();
116
    }
117
118
    /**
119
     * @param string $table
120
     * @param array $row
121
     * @param string $status
122
     * @param string $iconName
123
     * @return string
124
     */
125
    public function postOverlayPriorityLookup($table, $row, &$status, $iconName)
0 ignored issues
show
Unused Code introduced by
The parameter $status is not used and could be removed. ( Ignorable by Annotation )

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

125
    public function postOverlayPriorityLookup($table, $row, /** @scrutinizer ignore-unused */ &$status, $iconName)

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

Loading history...
126
    {
127
        if ($this->isMappingAvailableForTableAndUid($row['uid'], $table)) {
128
            $mapping = $this->getMappingRepository()->findOneByForeignTableNameAndUid($row['uid'], $table);
129
            if ($mapping instanceof Mapping) {
0 ignored issues
show
introduced by
$mapping is always a sub-type of Aoe\FeatureFlag\Domain\Model\Mapping.
Loading history...
130
                if ($row['hidden'] === '1') {
131
                    return 'record-has-feature-flag-which-is-hidden';
132
                }
133
                if ($iconName !== '') {
134
                    // if record is e.g. hidden or protected by FE-group, than show that (e.g. 'hidden' or 'fe_group'-)overlay as default
135
                    return $iconName;
136
                }
137
                return 'record-has-feature-flag-which-is-visible';
138
            }
139
        }
140
141
        // return given icon-name as fall-back
142
        return $iconName;
143
    }
144
145
    /**
146
     * @param string $table
147
     * @param int $id
148
     * @param int $featureFlag
149
     * @param int $pid
150
     * @param string $behavior
151
     */
152
    protected function updateMapping($table, $id, $featureFlag, $pid, $behavior)
153
    {
154
        $mapping = $this->getMappingRepository()->findOneByForeignTableNameAndUid($id, $table);
155
        if ($mapping instanceof Mapping) {
0 ignored issues
show
introduced by
$mapping is always a sub-type of Aoe\FeatureFlag\Domain\Model\Mapping.
Loading history...
156
            if ('0' === $featureFlag) {
0 ignored issues
show
introduced by
The condition '0' === $featureFlag is always false.
Loading history...
157
                $this->getMappingRepository()->remove($mapping);
158
            } else {
159
                $mapping->setFeatureFlag($this->getFeatureFlagByUid($featureFlag));
160
                $mapping->setBehavior($behavior);
161
            }
162
            $mapping->setTstamp(time());
163
            $this->getMappingRepository()->update($mapping);
164
        } elseif ('0' !== $featureFlag) {
165
            /** @var Mapping $mapping */
166
            $mapping = $this->getObjectManager()->get(Mapping::class);
167
            $mapping->setPid($pid);
168
            $mapping->setFeatureFlag($this->getFeatureFlagByUid($featureFlag));
169
            $mapping->setForeignTableName($table);
170
            $mapping->setForeignTableUid($id);
171
            $mapping->setCrdate(time());
172
            $mapping->setTstamp(time());
173
            $mapping->setBehavior($behavior);
174
            $this->getMappingRepository()->add($mapping);
175
        }
176
        $this->getPersistenceManager()->persistAll();
177
    }
178
179
    /**
180
     * @param int $foreignTableUid
181
     * @param string $foreignTableName
182
     * @return bool
183
     */
184
    protected function isMappingAvailableForTableAndUid($foreignTableUid, $foreignTableName)
185
    {
186
        if (null === self::$hashedMappings) {
187
            self::$hashedMappings = $this->getMappingRepository()->getHashedMappings();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getMappingReposit...()->getHashedMappings() of type array or array is incompatible with the declared type TYPO3\CMS\Extbase\Persistence\QueryResultInterface of property $hashedMappings.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
188
        }
189
        $identifier = sha1($foreignTableUid . '_' . $foreignTableName);
190
        if (array_key_exists($identifier, self::$hashedMappings)) {
0 ignored issues
show
Bug introduced by
It seems like self::hashedMappings can also be of type TYPO3\CMS\Extbase\Persistence\QueryResultInterface; however, parameter $array of array_key_exists() does only seem to accept ArrayObject|array, maybe add an additional type check? ( Ignorable by Annotation )

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

190
        if (array_key_exists($identifier, /** @scrutinizer ignore-type */ self::$hashedMappings)) {
Loading history...
191
            return true;
192
        }
193
194
        return false;
195
    }
196
197
    /**
198
     * @param int $uid
199
     * @return FeatureFlag
200
     * @throws FeatureNotFoundException
201
     */
202
    protected function getFeatureFlagByUid($uid)
203
    {
204
        /** @var FeatureFlag $featureFlag */
205
        $featureFlag = $this->getFeatureFlagRepository()->findByUid($uid);
206
        if (false === ($featureFlag instanceof FeatureFlag)) {
207
            throw new FeatureNotFoundException(
208
                'Feature Flag not found by uid: "' . $uid . '"',
209
                1384340431
210
            );
211
        }
212
213
        return $featureFlag;
214
    }
215
216
    /**
217
     * @return MappingRepository
218
     */
219
    protected function getMappingRepository()
220
    {
221
        return $this->getObjectManager()->get(MappingRepository::class);
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Extbase\Object\ObjectManager::get() has been deprecated: since TYPO3 10.4, will be removed in version 12.0 ( Ignorable by Annotation )

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

221
        return /** @scrutinizer ignore-deprecated */ $this->getObjectManager()->get(MappingRepository::class);

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

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

Loading history...
222
    }
223
224
    /**
225
     * @return FeatureFlagRepository
226
     */
227
    protected function getFeatureFlagRepository()
228
    {
229
        return $this->getObjectManager()->get(FeatureFlagRepository::class);
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Extbase\Object\ObjectManager::get() has been deprecated: since TYPO3 10.4, will be removed in version 12.0 ( Ignorable by Annotation )

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

229
        return /** @scrutinizer ignore-deprecated */ $this->getObjectManager()->get(FeatureFlagRepository::class);

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

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

Loading history...
230
    }
231
232
    /**
233
     * @return ObjectManager
234
     */
235
    protected function getObjectManager()
236
    {
237
        if (false === ($this->objectManager instanceof ObjectManager)) {
238
            $this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
239
        }
240
241
        return $this->objectManager;
242
    }
243
244
    /**
245
     * @return PersistenceManager
246
     */
247
    protected function getPersistenceManager()
248
    {
249
        if (false === $this->persistenceManager instanceof PersistenceManager) {
250
            $this->persistenceManager = $this->getObjectManager()->get(PersistenceManager::class);
0 ignored issues
show
Deprecated Code introduced by
The function TYPO3\CMS\Extbase\Object\ObjectManager::get() has been deprecated: since TYPO3 10.4, will be removed in version 12.0 ( Ignorable by Annotation )

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

250
            $this->persistenceManager = /** @scrutinizer ignore-deprecated */ $this->getObjectManager()->get(PersistenceManager::class);

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

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

Loading history...
251
        }
252
253
        return $this->persistenceManager;
254
    }
255
256
    /**
257
     * @return LanguageService
258
     */
259
    protected function getLanguageService()
260
    {
261
        return $GLOBALS['LANG'];
262
    }
263
}
264