cb9119adfc443d8b23963f648e03361f6a514548
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Context / UserAspect.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Core\Context;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use TYPO3\CMS\Core\Authentication\AbstractUserAuthentication;
19 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
20 use TYPO3\CMS\Core\Context\Exception\AspectPropertyNotFoundException;
21 use TYPO3\CMS\Core\Utility\GeneralUtility;
22 use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
23
24 /**
25 * The aspect contains information about a user.
26 * Can be used for frontend and backend users.
27 *
28 * Allowed properties:
29 * - id
30 * - username
31 * - isLoggedIn
32 * - groupIds (Array of Ids)
33 * - groupNames
34 */
35 class UserAspect implements AspectInterface
36 {
37 /**
38 * @var AbstractUserAuthentication
39 */
40 protected $user;
41
42 /**
43 * Alternative list of groups, usually useful for frontend logins with "magic" groups like "-1" and "-2"
44 *
45 * @var int[]
46 */
47 protected $groups;
48
49 /**
50 * @param AbstractUserAuthentication|null $user
51 * @param array|null $alternativeGroups
52 */
53 public function __construct(AbstractUserAuthentication $user = null, array $alternativeGroups = null)
54 {
55 $this->user = $user ?? (object)['user' => []];
56 $this->groups = $alternativeGroups;
57 }
58
59 /**
60 * Fetch common information about the user
61 *
62 * @param string $name
63 * @return int|bool|string|array
64 * @throws AspectPropertyNotFoundException
65 */
66 public function get(string $name)
67 {
68 switch ($name) {
69 case 'id':
70 return (int)($this->user->user[$this->user->userid_column ?? 'uid'] ?? 0);
71 case 'username':
72 return (string)($this->user->user[$this->user->username_column ?? 'username'] ?? '');
73 case 'isLoggedIn':
74 return $this->isLoggedIn();
75 case 'isAdmin':
76 return $this->isAdmin();
77 case 'groupIds':
78 return $this->getGroupIds();
79 case 'groupNames':
80 return $this->getGroupNames();
81 }
82 throw new AspectPropertyNotFoundException('Property "' . $name . '" not found in Aspect "' . __CLASS__ . '".', 1529996567);
83 }
84
85 /**
86 * If a frontend user is checked, he/she also needs to have a group, otherwise it is only
87 * checked if the frontend user has a uid > 0
88 *
89 * @return bool
90 */
91 public function isLoggedIn(): bool
92 {
93 if ($this->user instanceof FrontendUserAuthentication) {
94 return ($this->user->user[$this->user->userid_column ?? 'uid'] ?? 0) > 0 && !empty($this->user->groupData['uid'] ?? null);
95 }
96 return ($this->user->user[$this->user->userid_column ?? 'uid'] ?? 0) > 0;
97 }
98
99 /**
100 * Check if admin is set
101 *
102 * @return bool
103 */
104 public function isAdmin(): bool
105 {
106 return $this->user->user['admin'] === 1 ?? false;
107 }
108
109 /**
110 * Return the groups the user is a member of
111 *
112 * For Frontend Users there are two special groups:
113 * "-1" = hide at login
114 * "-2" = show at any login
115 *
116 * @return array
117 */
118 public function getGroupIds(): array
119 {
120 $groups = [];
121 if ($this->user instanceof BackendUserAuthentication) {
122 $groups = GeneralUtility::intExplode(',', $this->user->groupList, true);
123 }
124 if ($this->user instanceof FrontendUserAuthentication) {
125 // Alternative groups are set
126 if (is_array($this->groups)) {
127 $groups = $this->groups;
128 } elseif ($this->isLoggedIn()) {
129 // If a user is logged in, always add "-2"
130 $groups = [0, -2];
131 if (!empty($this->user->groupData['uid'])) {
132 $groups = array_merge($groups, array_map('intval', $this->user->groupData['uid']));
133 }
134 } else {
135 $groups = [0, -1];
136 }
137 }
138 return $groups;
139 }
140
141 /**
142 * Get the name of all groups, used in Fluid's IfHasRole ViewHelper
143 *
144 * @return array
145 */
146 public function getGroupNames(): array
147 {
148 $groupNames = [];
149 if ($this->user instanceof FrontendUserAuthentication) {
150 $groupNames = $this->user->groupData['title'];
151 }
152 if ($this->user instanceof BackendUserAuthentication) {
153 foreach ($this->user->userGroups as $userGroup) {
154 $groupNames[] = $userGroup['title'];
155 }
156 }
157 return $groupNames;
158 }
159
160 /**
161 * Checking if a user is logged in or a group constellation different from "0,-1"
162 *
163 * @return bool TRUE if either a login user is found OR if the group list is set to something else than '0,-1' (could be done even without a user being logged in!)
164 */
165 public function isUserOrGroupSet(): bool
166 {
167 if ($this->user instanceof FrontendUserAuthentication) {
168 $groups = $this->getGroupIds();
169 return is_array($this->user->user ?? null) || implode(',', $groups) !== '0,-1';
170 }
171 return $this->isLoggedIn();
172 }
173 }