TCA::isMappingAvailableForTableAndUid()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
nc 2
nop 2
dl 0
loc 9
ccs 0
cts 3
cp 0
crap 6
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace Aoe\FeatureFlag\System\Typo3;
4
5
/***************************************************************
6
 *  Copyright notice
7
 *
8
 *  (c) 2024 AOE GmbH <[email protected]>
9
 *
10
 *  All rights reserved
11
 *
12
 *  This script is part of the TYPO3 project. The TYPO3 project is
13
 *  free software; you can redistribute it and/or modify
14
 *  it under the terms of the GNU General Public License as published by
15
 *  the Free Software Foundation; either version 3 of the License, or
16
 *  (at your option) any later version.
17
 *
18
 *  The GNU General Public License can be found at
19
 *  http://www.gnu.org/copyleft/gpl.html.
20
 *
21
 *  This script is distributed in the hope that it will be useful,
22
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 *  GNU General Public License for more details.
25
 *
26
 *  This copyright notice MUST APPEAR in all copies of the script!
27
 ***************************************************************/
28
29
use Aoe\FeatureFlag\Domain\Model\FeatureFlag;
30
use Aoe\FeatureFlag\Domain\Model\Mapping;
31
use Aoe\FeatureFlag\Domain\Repository\FeatureFlagRepository;
32
use Aoe\FeatureFlag\Domain\Repository\MappingRepository;
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\Persistence\Generic\PersistenceManager;
37
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
38
39
class TCA
40
{
41
    /**
42
     * @var string
43
     */
44
    public const FIELD_BEHAVIOR = 'tx_featureflag_behavior';
45
46
    /**
47
     * @var string
48
     */
49
    public const FIELD_FLAG = 'tx_featureflag_flag';
50
51
    protected static ?array $hashedMappings = null;
52
53
    /**
54
     * Hook for updates in Typo3 backend
55
     * @codingStandardsIgnoreStart
56
     */
57
    public function processDatamap_preProcessFieldArray(
58
        array &$incomingFieldArray,
59
        string $table,
60
        string $id,
61
        DataHandler $dataHandler
62
    ): void {
63
        // @codingStandardsIgnoreEnd
64
        if (
65
            array_key_exists(self::FIELD_BEHAVIOR, $incomingFieldArray) &&
66
            array_key_exists(self::FIELD_FLAG, $incomingFieldArray)
67
        ) {
68
            $pid = $dataHandler->getPID($table, (int) $id);
69
            $this->updateMapping(
70
                $table,
71
                (int) $id,
72
                $incomingFieldArray[self::FIELD_FLAG],
73
                (int) $pid,
74
                $incomingFieldArray[self::FIELD_BEHAVIOR]
75
            );
76
            unset($incomingFieldArray[self::FIELD_BEHAVIOR]);
77
            unset($incomingFieldArray[self::FIELD_FLAG]);
78
        }
79
    }
80
81
    /**
82
     * Hook for deletes in Typo3 Backend. It also delete all overwrite protection
83
     * @codingStandardsIgnoreStart
84
     */
85
    public function processCmdmap_postProcess(string $command, string $table, int $id): void
86
    {
87
        // @codingStandardsIgnoreEnd
88
        if ($command !== 'delete') {
89
            return;
90
        }
91
92
        $mappings = $this->getMappingRepository()
93
            ->findAllByForeignTableNameAndUid($id, $table);
94
        if (!is_array($mappings) && !$mappings instanceof QueryResultInterface) {
95
            return;
96
        }
97
98
        foreach ($mappings as $mapping) {
99
            if ($mapping instanceof Mapping) {
100
                $this->getMappingRepository()
101
                    ->remove($mapping);
102
            }
103
        }
104
105
        $this->getPersistenceManager()
106
            ->persistAll();
107
    }
108
109
    public function postOverlayPriorityLookup(string $table, array $row, array $status, string $iconName): string
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

109
    public function postOverlayPriorityLookup(string $table, array $row, /** @scrutinizer ignore-unused */ array $status, string $iconName): string

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...
110
    {
111
        if (!empty($row['uid']) && $this->isMappingAvailableForTableAndUid($row['uid'], $table)) {
112
            $mapping = $this->getMappingRepository()
113
                ->findOneByForeignTableNameAndUid($row['uid'], $table);
114
            if ($mapping instanceof Mapping) {
115
                if ($row['hidden'] === '1') {
116
                    return 'record-has-feature-flag-which-is-hidden';
117
                }
118
119
                if ($iconName !== '') {
120
                    // if record is e.g. hidden or protected by FE-group, than show that (e.g. 'hidden' or 'fe_group'-)overlay as default
121
                    return $iconName;
122
                }
123
124
                return 'record-has-feature-flag-which-is-visible';
125
            }
126
        }
127
128
        // return given icon-name as fall-back
129
        return $iconName;
130
    }
131
132
    /**
133
     * @todo fix code style
134
     */
135
    protected function updateMapping(string $table, int $id, int $featureFlag, int $pid, string $behavior): void
136
    {
137
        $mapping = $this->getMappingRepository()
138
            ->findOneByForeignTableNameAndUid($id, $table);
139
140
        if ($mapping instanceof Mapping) {
141
            if ($featureFlag === 0) {
142
                $this->getMappingRepository()
143
                    ->remove($mapping);
144
            } else {
145
                $mapping->setFeatureFlag($this->getFeatureFlagByUid($featureFlag));
146
                $mapping->setBehavior($behavior);
147
            }
148
149
            $mapping->setTstamp((string) time());
150
            $this->getMappingRepository()
151
                ->update($mapping);
152
        } elseif ($featureFlag !== 0) {
153
            /** @var Mapping $mapping */
154
            $mapping = new Mapping();
155
            $mapping->setPid($pid);
156
            $mapping->setFeatureFlag($this->getFeatureFlagByUid($featureFlag));
157
            $mapping->setForeignTableName($table);
158
            $mapping->setForeignTableUid($id);
159
            $mapping->setCrdate((string) time());
160
            $mapping->setTstamp((string) time());
161
            $mapping->setBehavior($behavior);
162
            $this->getMappingRepository()
163
                ->add($mapping);
164
        }
165
166
        $this->getPersistenceManager()
167
            ->persistAll();
168
    }
169
170
    protected function isMappingAvailableForTableAndUid(string $foreignTableUid, string $foreignTableName): bool
171
    {
172
        if (self::$hashedMappings === null) {
173
            self::$hashedMappings = $this->getMappingRepository()->getHashedMappings();
174
        }
175
176
        $identifier = sha1($foreignTableUid . '_' . $foreignTableName);
177
178
        return array_key_exists($identifier, self::$hashedMappings);
179
    }
180
181
    protected function getFeatureFlagByUid(int $uid): FeatureFlag
182
    {
183
        /** @var FeatureFlag $featureFlag */
184
        $featureFlag = $this->getFeatureFlagRepository()
185
            ->findByUid($uid);
186
187
        return $featureFlag;
188
    }
189
190
    protected function getMappingRepository(): object
191
    {
192
        return GeneralUtility::makeInstance(MappingRepository::class);
193
    }
194
195
    protected function getFeatureFlagRepository(): object
196
    {
197
        return GeneralUtility::makeInstance(FeatureFlagRepository::class);
198
    }
199
200
    protected function getPersistenceManager(): object
201
    {
202
        return GeneralUtility::makeInstance(PersistenceManager::class);
203
    }
204
205
    protected function getLanguageService(): LanguageService
206
    {
207
        return $GLOBALS['LANG'];
208
    }
209
}
210