Revisions: Style action links in old revision notices as links
[mediawiki.git] / includes / user / UserGroupMembership.php
blob83c1d56c9d35e1abae4823a6877b4afaa20b08b7
1 <?php
2 /**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
18 * @file
21 namespace MediaWiki\User;
23 use InvalidArgumentException;
24 use MediaWiki\Context\IContextSource;
25 use MediaWiki\MediaWikiServices;
26 use MediaWiki\Message\Message;
27 use MediaWiki\Title\Title;
29 /**
30 * Represents the membership of one user in one user group.
32 * For example, if user "Mary" belongs to "sysop" and "bureaucrat" groups,
33 * those memberships can be represented by two UserGroupMembership objects.
35 * The class is a value object. Use UserGroupManager to modify user group memberships.
37 * @since 1.29
38 * @ingroup User
40 class UserGroupMembership {
42 /** @var int The ID of the user who belongs to the group */
43 private $userId;
45 /** @var string */
46 private $group;
48 /** @var string|null Timestamp of expiry in TS_MW format, or null if no expiry */
49 private $expiry;
51 /** @var bool Expiration flag */
52 private $expired;
54 /**
55 * @param int $userId The ID of the user who belongs to the group
56 * @param string|null $group The internal group name
57 * @param string|null $expiry Timestamp of expiry in TS_MW format, or null if no expiry
59 public function __construct( int $userId = 0, ?string $group = null, ?string $expiry = null ) {
60 $this->userId = $userId;
61 $this->group = $group;
62 $this->expiry = $expiry ?: null;
63 $this->expired = $expiry && wfTimestampNow() > $expiry;
66 /**
67 * @return int
69 public function getUserId() {
70 return $this->userId;
73 /**
74 * @return string
76 public function getGroup() {
77 return $this->group;
80 /**
81 * @return string|null Timestamp of expiry in TS_MW format, or null if no expiry
83 public function getExpiry() {
84 return $this->expiry;
87 /**
88 * Has the membership expired?
90 * @return bool
92 public function isExpired() {
93 return $this->expired;
96 /**
97 * Gets a link for a user group, possibly including the expiry date if relevant.
99 * @deprecated since 1.41 use getLinkWiki or getLinkHTML directly
101 * @param string|UserGroupMembership $ugm Either a group name as a string, or
102 * a UserGroupMembership object
103 * @param IContextSource $context
104 * @param string $format Either 'wiki' or 'html'
105 * @param string|null $userName If you want to use the group member message
106 * ("administrator"), pass the name of the user who belongs to the group; it
107 * is used for GENDER of the group member message. If you instead want the
108 * group name message ("Administrators"), omit this parameter.
109 * @return string
111 public static function getLink( $ugm, IContextSource $context, string $format, $userName = null ) {
112 switch ( $format ) {
113 case 'wiki':
114 return self::getLinkWiki( $ugm, $context, $userName );
115 case 'html':
116 return self::getLinkHTML( $ugm, $context, $userName );
117 default:
118 throw new InvalidArgumentException( 'UserGroupMembership::getLink() $format parameter should be ' .
119 "'wiki' or 'html'" );
124 * Gets a link for a user group, possibly including the expiry date if relevant.
125 * @since 1.41
127 * @param string|UserGroupMembership $ugm Either a group name as a string, or
128 * a UserGroupMembership object
129 * @param IContextSource $context
130 * @param string|null $userName If you want to use the group member message
131 * ("administrator"), pass the name of the user who belongs to the group; it
132 * is used for GENDER of the group member message. If you instead want the
133 * group name message ("Administrators"), omit this parameter.
134 * @return string
136 public static function getLinkHTML( $ugm, IContextSource $context, $userName = null ): string {
138 'expiry' => $expiry,
139 'linkTitle' => $linkTitle,
140 'groupName' => $groupName
141 ] = self::getLinkInfo( $ugm, $context, $userName );
143 // link to the group description page, if it exists
144 $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
145 if ( $linkTitle ) {
146 $groupLink = $linkRenderer->makeLink( $linkTitle, $groupName );
147 } else {
148 $groupLink = htmlspecialchars( $groupName );
151 if ( $expiry ) {
153 'expiryDT' => $expiryDT,
154 'expiryD' => $expiryD,
155 'expiryT' => $expiryT
156 ] = self::getLinkExpiryParams( $context, $expiry );
157 $groupLink = Message::rawParam( $groupLink );
158 return $context->msg( 'group-membership-link-with-expiry' )
159 ->params( $groupLink, $expiryDT, $expiryD, $expiryT )->escaped();
161 return $groupLink;
165 * Gets a link for a user group, possibly including the expiry date if relevant.
166 * @since 1.41
168 * @param string|UserGroupMembership $ugm Either a group name as a string, or
169 * a UserGroupMembership object
170 * @param IContextSource $context
171 * @param string|null $userName If you want to use the group member message
172 * ("administrator"), pass the name of the user who belongs to the group; it
173 * is used for GENDER of the group member message. If you instead want the
174 * group name message ("Administrators"), omit this parameter.
175 * @return string
177 public static function getLinkWiki( $ugm, IContextSource $context, $userName = null ): string {
179 'expiry' => $expiry,
180 'linkTitle' => $linkTitle,
181 'groupName' => $groupName
182 ] = self::getLinkInfo( $ugm, $context, $userName );
184 // link to the group description page, if it exists
185 if ( $linkTitle ) {
186 $linkPage = $linkTitle->getFullText();
187 $groupLink = "[[$linkPage|$groupName]]";
188 } else {
189 $groupLink = $groupName;
192 if ( $expiry ) {
194 'expiryDT' => $expiryDT,
195 'expiryD' => $expiryD,
196 'expiryT' => $expiryT
197 ] = self::getLinkExpiryParams( $context, $expiry );
198 return $context->msg( 'group-membership-link-with-expiry' )
199 ->params( $groupLink, $expiryDT, $expiryD, $expiryT )->text();
201 return $groupLink;
205 * @param self|string $ugm
206 * @param IContextSource $context
207 * @param string|null $userName
208 * @return array
210 private static function getLinkInfo( $ugm, $context, $userName = null ): array {
211 if ( $ugm instanceof UserGroupMembership ) {
212 $expiry = $ugm->getExpiry();
213 $group = $ugm->getGroup();
214 } else {
215 $expiry = null;
216 $group = $ugm;
219 $uiLanguage = $context->getLanguage();
220 if ( $userName !== null ) {
221 $groupName = $uiLanguage->getGroupMemberName( $group, $userName );
222 } else {
223 $groupName = $uiLanguage->getGroupName( $group );
225 $linkTitle = self::getGroupPage( $group );
226 return [ 'expiry' => $expiry, 'linkTitle' => $linkTitle, 'groupName' => $groupName ];
230 * @param IContextSource $context
231 * @param string $expiry
232 * @return array
234 private static function getLinkExpiryParams( IContextSource $context, string $expiry ): array {
235 // format the expiry to a nice string
236 $uiLanguage = $context->getLanguage();
237 $uiUser = $context->getUser();
238 $expiryDT = $uiLanguage->userTimeAndDate( $expiry, $uiUser );
239 $expiryD = $uiLanguage->userDate( $expiry, $uiUser );
240 $expiryT = $uiLanguage->userTime( $expiry, $uiUser );
241 return [ 'expiryDT' => $expiryDT, 'expiryD' => $expiryD, 'expiryT' => $expiryT ];
245 * Gets the title of a page describing a particular user group. When the name
246 * of the group appears in the UI, it can link to this page.
248 * @param string $group Internal group name
249 * @return Title|false Title of the page if it exists, false otherwise
251 public static function getGroupPage( $group ) {
252 $msg = wfMessage( "grouppage-$group" )->inContentLanguage();
253 if ( $msg->exists() ) {
254 $title = Title::newFromText( $msg->text() );
255 if ( is_object( $title ) ) {
256 return $title;
259 return false;
263 * Compares two pure value objects
265 * @param UserGroupMembership $ugm
266 * @return bool
268 * @since 1.35
270 public function equals( UserGroupMembership $ugm ) {
271 return (
272 $ugm->getUserId() === $this->userId
273 && $ugm->getGroup() === $this->group
279 /** @deprecated class alias since 1.41 */
280 class_alias( UserGroupMembership::class, 'UserGroupMembership' );