• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

FluidTYPO3 / vhs / 28587738246

02 Jul 2026 11:50AM UTC coverage: 69.886% (+0.1%) from 69.743%
28587738246

push

github

NamelessCoder
[TASK] Remove some always-true or always-false conditions

0 of 2 new or added lines in 2 files covered. (0.0%)

4827 of 6907 relevant lines covered (69.89%)

4.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

65.61
/Classes/ViewHelpers/Security/AbstractSecurityViewHelper.php
1
<?php
2
namespace FluidTYPO3\Vhs\ViewHelpers\Security;
3

4
/*
5
 * This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
6
 *
7
 * For the full copyright and license information, please read the
8
 * LICENSE.md file that was distributed with this source code.
9
 */
10

11
use FluidTYPO3\Vhs\Utility\ContextUtility;
12
use Psr\Http\Message\ServerRequestInterface;
13
use TYPO3\CMS\Core\Context\Context;
14
use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException;
15
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
16
use TYPO3\CMS\Core\Utility\GeneralUtility;
17
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
18
use TYPO3\CMS\Extbase\Domain\Model\BackendUser;
19
use TYPO3\CMS\Extbase\Domain\Model\FrontendUser;
20
use TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup;
21
use TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository;
22
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
23
use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
24
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
25
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
26
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
27

28
/**
29
 * Base class: Security ViewHelpers
30
 */
31
abstract class AbstractSecurityViewHelper extends AbstractConditionViewHelper
32
{
33
    /**
34
     * @var FrontendUserRepository
35
     */
36
    protected $frontendUserRepository;
37

38
    public function __construct()
39
    {
NEW
40
        if (!ExtensionManagementUtility::isLoaded('feuserextrafields')) {
×
41
            throw new \Exception('On TYPO3v12, v:security.* requires EXT:feuserextrafields', 1670521759);
×
42
        }
43
        /** @var FrontendUserRepository $frontendUserRepository */
44
        $frontendUserRepository = GeneralUtility::makeInstance(FrontendUserRepository::class);
×
45
        $this->frontendUserRepository = $frontendUserRepository;
×
46
        $query = $this->frontendUserRepository->createQuery();
×
47
        $querySettings = $query->getQuerySettings();
×
48
        $querySettings->setRespectStoragePage(false);
×
49
        $querySettings->setRespectSysLanguage(false);
×
50
        $this->frontendUserRepository->setDefaultQuerySettings($querySettings);
×
51
    }
52

53
    public function initializeArguments(): void
54
    {
55
        parent::initializeArguments();
6✔
56
        $this->registerArgument(
6✔
57
            'anyFrontendUser',
6✔
58
            'boolean',
6✔
59
            'If TRUE, allows any FrontendUser unless other arguments disallows each specific FrontendUser',
6✔
60
            false,
6✔
61
            false
6✔
62
        );
6✔
63
        $this->registerArgument(
6✔
64
            'anyFrontendUserGroup',
6✔
65
            'boolean',
6✔
66
            'If TRUE, allows any FrontendUserGroup unless other arguments disallows each specific FrontendUser',
6✔
67
            false,
6✔
68
            false
6✔
69
        );
6✔
70
        $this->registerArgument(
6✔
71
            'frontendUser',
6✔
72
            FrontendUser::class,
6✔
73
            'The FrontendUser to allow/deny'
6✔
74
        );
6✔
75
        $this->registerArgument(
6✔
76
            'frontendUsers',
6✔
77
            '<TYPO3\CMS\Extbase\Persistence\ObjectStorage>\TYPO3\CMS\Extbase\Domain\Model\FrontendUser',
6✔
78
            'The FrontendUsers ObjectStorage to allow/deny'
6✔
79
        );
6✔
80
        $this->registerArgument(
6✔
81
            'frontendUserGroup',
6✔
82
            FrontendUserGroup::class,
6✔
83
            'The FrontendUserGroup to allow/deny'
6✔
84
        );
6✔
85
        $this->registerArgument(
6✔
86
            'frontendUserGroups',
6✔
87
            '<TYPO3\CMS\Extbase\Persistence\ObjectStorage>\TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup',
6✔
88
            'The FrontendUserGroups ObjectStorage to allow/deny'
6✔
89
        );
6✔
90
        $this->registerArgument(
6✔
91
            'anyBackendUser',
6✔
92
            'boolean',
6✔
93
            'If TRUE, allows any backend user unless other arguments disallows each specific backend user',
6✔
94
            false,
6✔
95
            false
6✔
96
        );
6✔
97
        $this->registerArgument(
6✔
98
            'backendUser',
6✔
99
            'integer',
6✔
100
            'The uid of a backend user to allow/deny'
6✔
101
        );
6✔
102
        $this->registerArgument(
6✔
103
            'backendUsers',
6✔
104
            'mixed',
6✔
105
            'The backend users list to allow/deny. If string, CSV of uids assumed, if array, array of uids assumed'
6✔
106
        );
6✔
107
        $this->registerArgument(
6✔
108
            'backendUserGroup',
6✔
109
            'integer',
6✔
110
            'The uid of the backend user group to allow/deny'
6✔
111
        );
6✔
112
        $this->registerArgument(
6✔
113
            'backendUserGroups',
6✔
114
            'mixed',
6✔
115
            'The backend user groups list to allow/deny. If string, CSV of uids is assumed, if array, ' .
6✔
116
            'array of uids is assumed'
6✔
117
        );
6✔
118
        $this->registerArgument(
6✔
119
            'admin',
6✔
120
            'boolean',
6✔
121
            'If TRUE, a backend user which is also an admin is required'
6✔
122
        );
6✔
123
        $this->registerArgument(
6✔
124
            'evaluationType',
6✔
125
            'string',
6✔
126
            'Specify AND or OR (case sensitive) to determine how arguments must be processed. Default is AND, ' .
6✔
127
            'requiring all arguments to be satisfied if used',
6✔
128
            false,
6✔
129
            'AND'
6✔
130
        );
6✔
131
    }
132

133
    public static function verdict(array $arguments, RenderingContextInterface $renderingContext): bool
134
    {
135
        /** @var static $proxy */
136
        $proxy = GeneralUtility::makeInstance(static::class);
2✔
137
        $proxy->setArguments((array) $arguments);
2✔
138
        return $proxy->evaluateArguments();
2✔
139
    }
140

141

142
    /**
143
     * Returns TRUE if all conditions from arguments are satisfied. The
144
     * type of evaluation (AND or OR) can be set using argument "evaluationType".
145
     */
146
    public function evaluateArguments(): bool
147
    {
148
        /** @var FrontendUser|null $frontendUser */
149
        $frontendUser = $this->arguments['frontendUser'] ?? null;
2✔
150

151
        /** @var ObjectStorage|null $frontendUsers */
152
        $frontendUsers = $this->arguments['frontendUsers'] ?? null;
2✔
153

154
        /** @var BackendUser|null $backendUser */
155
        $backendUser = $this->arguments['backendUser'] ?? null;
2✔
156

157
        $evaluationType = $this->arguments['evaluationType'];
2✔
158
        $evaluations = [];
2✔
159
        if ($this->arguments['anyFrontendUser'] ?? false) {
2✔
160
            $evaluations['anyFrontendUser'] = intval($this->assertFrontendUserLoggedIn());
×
161
        }
162
        if ($this->arguments['anyFrontendUserGroup'] ?? false) {
2✔
163
            $evaluations['anyFrontendUserGroup'] = intval($this->assertFrontendUserGroupLoggedIn());
×
164
        }
165
        if ($frontendUser) {
2✔
166
            $evaluations['frontendUser'] = intval($this->assertFrontendUserLoggedIn($frontendUser));
×
167
        }
168
        if ($frontendUsers) {
2✔
169
            $evaluations['frontendUsers'] = intval($this->assertFrontendUsersLoggedIn($frontendUsers));
×
170
        }
171
        if (isset($this->arguments['frontendUserGroup'])) {
2✔
172
            $evaluations['frontendUserGroup'] =
×
173
                intval($this->assertFrontendUserGroupLoggedIn($this->arguments['frontendUserGroup']));
×
174
        }
175
        if (isset($this->arguments['frontendUserGroups'])) {
2✔
176
            $evaluations['frontendUserGroups'] =
×
177
                intval($this->assertFrontendUserGroupLoggedIn($this->arguments['frontendUserGroups']));
×
178
        }
179
        if ($this->arguments['anyBackendUser'] ?? false) {
2✔
180
            $evaluations['anyBackendUser'] = intval($this->assertBackendUserLoggedIn());
2✔
181
        }
182
        if ($this->arguments['anyBackendUserGroup'] ?? false) {
2✔
183
            $evaluations['anyBackendUserGroup'] = intval($this->assertBackendUserGroupLoggedIn());
×
184
        }
185
        if (isset($this->arguments['backendUser'])) {
2✔
186
            $evaluations['backendUser'] = intval($this->assertBackendUserLoggedIn($backendUser));
×
187
        }
188
        if (isset($this->arguments['backendUsers'])) {
2✔
189
            $evaluations['backendUsers'] = intval($this->assertBackendUserLoggedIn($backendUser));
×
190
        }
191
        if (isset($this->arguments['backendUserGroup'])) {
2✔
192
            $evaluations['backendUserGroup'] =
×
193
                intval($this->assertBackendUserGroupLoggedIn($this->arguments['backendUserGroup']));
×
194
        }
195
        if (isset($this->arguments['backendUserGroups'])) {
2✔
196
            $evaluations['backendUserGroups'] =
×
197
                intval($this->assertBackendUserGroupLoggedIn($this->arguments['backendUserGroups']));
×
198
        }
199
        if ($this->arguments['admin'] ?? false) {
2✔
200
            $evaluations['admin'] = intval($this->assertAdminLoggedIn());
×
201
        }
202
        $sum = array_sum($evaluations);
2✔
203
        return 'AND' === $evaluationType ? count($evaluations) === $sum : $sum > 0;
2✔
204
    }
205

206
    /**
207
     * Returns TRUE only if a FrontendUser is currently logged in. Use argument
208
     * to return TRUE only if the FrontendUser logged in must be that specific user.
209
     *
210
     * @param int|FrontendUser|null $frontendUser
211
     */
212
    public function assertFrontendUserLoggedIn($frontendUser = null): bool
213
    {
214
        $currentFrontendUser = $this->getCurrentFrontendUser();
×
215
        if (!$currentFrontendUser instanceof FrontendUser) {
×
216
            return false;
×
217
        }
218
        if ($frontendUser instanceof FrontendUser) {
×
219
            if ($currentFrontendUser->getUid() === $frontendUser->getUid()) {
×
220
                return true;
×
221
            } else {
222
                return false;
×
223
            }
224
        }
225
        return is_object($currentFrontendUser);
×
226
    }
227

228
    /**
229
     * Returns TRUE only if currently logged in frontend user is in list.
230
     */
231
    public function assertFrontendUsersLoggedIn(?ObjectStorage $frontendUsers = null): bool
232
    {
233
        if ($frontendUsers === null) {
×
234
            return false;
×
235
        }
236
        /** @var FrontendUser[] $frontendUsers */
237
        foreach ($frontendUsers as $frontendUser) {
×
238
            if ($this->assertFrontendUserLoggedIn($frontendUser)) {
×
239
                return true;
×
240
            }
241
        }
242
        return false;
×
243
    }
244

245
    /**
246
     * Returns TRUE if a FrontendUserGroup (specific given argument, else not) is logged in
247
     *
248
     * @param mixed $groups One \TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup or ObjectStorage containing same
249
     */
250
    public function assertFrontendUserGroupLoggedIn($groups = null): bool
251
    {
252
        $currentFrontendUser = $this->getCurrentFrontendUser();
×
253
        if (!$currentFrontendUser instanceof FrontendUser) {
×
254
            return false;
×
255
        }
256
        $currentFrontendUserGroups = $currentFrontendUser->getUsergroup();
×
257
        if (!$groups) {
×
258
            return (0 < $currentFrontendUserGroups->count());
×
259
        } elseif ($groups instanceof FrontendUserGroup) {
×
260
            return $currentFrontendUserGroups->contains($groups);
×
261
        } elseif ($groups instanceof ObjectStorage) {
×
262
            $currentFrontendUserGroupsClone = clone $currentFrontendUserGroups;
×
263
            $currentFrontendUserGroupsClone->removeAll($groups);
×
264
            return ($currentFrontendUserGroups->count() !== $currentFrontendUserGroupsClone->count());
×
265
        }
266
        return false;
×
267
    }
268

269
    /**
270
     * Returns TRUE only if a backend user is currently logged in. If used,
271
     * argument specifies that the logged in user must be that specific user
272
     *
273
     * @param int|BackendUser|null $backendUser
274
     */
275
    public function assertBackendUserLoggedIn($backendUser = null): bool
276
    {
277
        if ($backendUser instanceof BackendUser) {
34✔
278
            $backendUser = $backendUser->getUid();
×
279
        }
280
        $currentBackendUser = $this->getCurrentBackendUser();
34✔
281
        if (null !== $backendUser) {
34✔
282
            return ((int) ($currentBackendUser['uid'] ?? 0) === $backendUser);
10✔
283
        }
284
        return is_array($currentBackendUser);
24✔
285
    }
286

287
    /**
288
     * Returns TRUE only if a backend user is logged in and either has any group
289
     * (if param left out) or is a member of the group $groups or a group in
290
     * the array/CSV $groups
291
     *
292
     * @param mixed $groups Array of group uids or CSV of group uids or one group uid
293
     */
294
    public function assertBackendUserGroupLoggedIn($groups = null): bool
295
    {
296
        if (!$this->assertBackendUserLoggedIn()) {
20✔
297
            return false;
2✔
298
        }
299
        $currentBackendUser = $this->getCurrentBackendUser();
18✔
300
        $currentUserGroups = trim($currentBackendUser['usergroup'] ?? '', ',');
18✔
301
        /** @var array $userGroups */
302
        $userGroups = !empty($currentUserGroups) ? explode(',', $currentUserGroups) : [];
18✔
303
        if (0 === count($userGroups)) {
18✔
304
            return false;
2✔
305
        }
306
        if (is_string($groups)) {
16✔
307
            $groups = trim($groups, ',');
4✔
308
            /** @var array $groups */
309
            $groups = !empty($groups) ? explode(',', $groups) : [];
4✔
310
        }
311
        /** @var array $groups */
312
        if (count($groups) > 0) {
16✔
313
            return count(array_intersect($userGroups, (array) $groups)) > 0;
14✔
314
        }
315
        return false;
2✔
316
    }
317

318
    /**
319
     * Returns TRUE only if there is a current user logged in and this user
320
     * is an admin class backend user.
321
     */
322
    public function assertAdminLoggedIn(): bool
323
    {
324
        /** @var Context $context */
325
        $context = GeneralUtility::makeInstance(Context::class);
×
326
        try {
327
            return (bool) $context->getPropertyFromAspect('backend.user', 'isAdmin');
×
328
        } catch (AspectNotFoundException $e) {
×
329
            return false;
×
330
        }
331
    }
332

333
    /**
334
     * Gets the currently logged in Frontend User.
335
     */
336
    public function getCurrentFrontendUser(): ?FrontendUser
337
    {
338
        if (empty($GLOBALS['TSFE']->loginUser)) {
2✔
339
            return null;
2✔
340
        }
341

342
        $frontendUserAuthentication = null;
×
343
        if ($GLOBALS['TYPO3_REQUEST'] instanceof ServerRequestInterface) {
×
344
            /** @var FrontendUserAuthentication|null $frontendUserAuthentication */
345
            $frontendUserAuthentication = $GLOBALS['TYPO3_REQUEST']->getAttribute('frontend.user');
×
346
        }
347

348
        if ($frontendUserAuthentication === null) {
×
349
            /** @var TypoScriptFrontendController $tsfe */
350
            $tsfe = $GLOBALS['TSFE'];
×
351
            /** @var FrontendUserAuthentication $frontendUserAuthentication */
352
            $frontendUserAuthentication = $tsfe->fe_user;
×
353
        }
354

355
        /** @var FrontendUser|null $frontendUser */
356
        $frontendUser = $this->frontendUserRepository->findByUid($frontendUserAuthentication->user['uid'] ?? 0);
×
357
        return $frontendUser;
×
358
    }
359

360
    /**
361
     * Returns a be_user record as lowerCamelCase indexed array if a BE user is
362
     * currently logged in.
363
     */
364
    public function getCurrentBackendUser(): ?array
365
    {
366
        return $GLOBALS['BE_USER']->user;
14✔
367
    }
368

369
    /**
370
     * Override: forcibly disables page caching - a TRUE condition
371
     * in this ViewHelper means page content would be depending on
372
     * the current visitor's session/cookie/auth etc.
373
     *
374
     * Returns value of "then" attribute.
375
     * If then attribute is not set, iterates through child nodes and renders ThenViewHelper.
376
     * If then attribute is not set and no ThenViewHelper and no ElseViewHelper is found, all child nodes are rendered
377
     *
378
     * @return mixed rendered ThenViewHelper or contents of <f:if> if no ThenViewHelper was found
379
     */
380
    protected function renderThenChild(): mixed
381
    {
382
        if ($this->isFrontendContext()) {
2✔
383
            $GLOBALS['TSFE']->no_cache = 1;
2✔
384
        }
385
        return parent::renderThenChild();
2✔
386
    }
387

388
    /**
389
     * @codeCoverageIgnore
390
     */
391
    protected function isFrontendContext(): bool
392
    {
393
        return ContextUtility::isFrontend();
394
    }
395
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc