diff --git a/i18n/en.json b/i18n/en.json index 8bb306095..69d7f54d1 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -581,6 +581,7 @@ "abusefilter-blocked-domains-domain-header": "Domain", "abusefilter-blocked-domains-notes-header": "Notes", "abusefilter-blocked-domains-actions-header": "Actions", + "abusefilter-blocked-domains-addedby-header": "Added by", "abusefilter-blocked-domains-remove": "remove", "abusefilter-blocked-domains-remove-title": "Remove a blocked domain", "abusefilter-blocked-domains-remove-explanation-initial": "On this page you can remove a blocked domain", diff --git a/i18n/qqq.json b/i18n/qqq.json index 1ef9aa4dc..035dcaf44 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -625,6 +625,7 @@ "abusefilter-blocked-domains-domain-header": "Domain header in the table", "abusefilter-blocked-domains-notes-header": "Notes header in the table", "abusefilter-blocked-domains-actions-header": "Actions header in the table", + "abusefilter-blocked-domains-addedby-header": "Header for added by username in the table", "abusefilter-blocked-domains-remove": "Link to remove a domain from blocked list", "abusefilter-blocked-domains-remove-title": "Title of the special page on removing the domain from blocked list", "abusefilter-blocked-domains-remove-explanation-initial": "Explanation of the special page on removing the domain from blocked list", diff --git a/includes/BlockedDomainStorage.php b/includes/BlockedDomainStorage.php index c7f611e20..632de8669 100644 --- a/includes/BlockedDomainStorage.php +++ b/includes/BlockedDomainStorage.php @@ -199,7 +199,7 @@ class BlockedDomainStorage implements IDBAccessObject { if ( $content === null ) { return null; } - $content[] = [ 'domain' => $domain, 'notes' => $notes ]; + $content[] = [ 'domain' => $domain, 'notes' => $notes, 'addedBy' => $user->getName() ]; $comment = Message::newFromSpecifier( 'abusefilter-blocked-domains-domain-added-comment' ) ->params( $domain, $notes ) ->plain(); diff --git a/includes/Hooks/Handlers/EditPermissionHandler.php b/includes/Hooks/Handlers/EditPermissionHandler.php index a3714c87d..4b7e1743b 100644 --- a/includes/Hooks/Handlers/EditPermissionHandler.php +++ b/includes/Hooks/Handlers/EditPermissionHandler.php @@ -27,6 +27,8 @@ class EditPermissionHandler implements GetUserPermissionsErrorsHook, JsonValidat 'notes' ]; + private const JSON_OPTIONAL_FIELDS = [ 'addedBy' ]; + /** * @see https://www.mediawiki.org/wiki/Manual:Hooks/getUserPermissionsErrors * @@ -92,14 +94,29 @@ class EditPermissionHandler implements GetUserPermissionsErrorsHook, JsonValidat $entryNumber = 0; foreach ( $data as $element ) { $entryNumber++; - // Check if each element is an object with all known fields, and no other fields - if ( is_object( $element ) && count( get_object_vars( $element ) ) === count( self::JSON_OBJECT_FIELDS ) ) { + // Check if each element is an object with all known fields, allow optional fields but no other fields + if ( is_object( $element ) && count( get_object_vars( $element ) ) >= count( self::JSON_OBJECT_FIELDS ) ) { foreach ( self::JSON_OBJECT_FIELDS as $field ) { if ( !property_exists( $element, $field ) || !is_string( $element->{$field} ) ) { $isValid = false; break 2; } } + + foreach ( self::JSON_OPTIONAL_FIELDS as $field ) { + if ( property_exists( $element, $field ) && !is_string( $element->{$field} ) ) { + $isValid = false; + break 2; + } + } + foreach ( $element as $field => $value ) { + if ( + !in_array( $field, array_merge( self::JSON_OPTIONAL_FIELDS, self::JSON_OBJECT_FIELDS ) ) + ) { + $isValid = false; + break; + } + } } else { $isValid = false; break; diff --git a/includes/Special/BlockedExternalDomains.php b/includes/Special/BlockedExternalDomains.php index 96628c135..f0f08cfca 100644 --- a/includes/Special/BlockedExternalDomains.php +++ b/includes/Special/BlockedExternalDomains.php @@ -25,6 +25,7 @@ use IDBAccessObject; use MediaWiki\Extension\AbuseFilter\BlockedDomainStorage; use MediaWiki\Html\Html; use MediaWiki\SpecialPage\SpecialPage; +use MediaWiki\Title\TitleValue; use PermissionsError; use WANObjectCache; @@ -112,11 +113,19 @@ class BlockedExternalDomains extends SpecialPage { } $content = Html::element( 'th', [], $this->msg( 'abusefilter-blocked-domains-domain-header' )->text() ) . - Html::element( 'th', [], $this->msg( 'abusefilter-blocked-domains-notes-header' )->text() ) . - ( $userCanManage ? - Html::element( 'th', [ 'class' => 'unsortable' ], - $this->msg( 'abusefilter-blocked-domains-actions-header' )->text() ) : - '' ); + Html::element( 'th', [], $this->msg( 'abusefilter-blocked-domains-notes-header' )->text() ); + if ( $userCanManage ) { + $content .= Html::element( + 'th', + [], + $this->msg( 'abusefilter-blocked-domains-addedby-header' )->text() + ); + $content .= Html::element( + 'th', + [ 'class' => 'unsortable' ], + $this->msg( 'abusefilter-blocked-domains-actions-header' )->text() + ); + } $thead = Html::rawElement( 'tr', [], $content ); // Parsing each row is expensive, put it behind WAN cache @@ -163,6 +172,16 @@ class BlockedExternalDomains extends SpecialPage { $newRow .= Html::rawElement( 'td', [], $this->getOutput()->parseInlineAsInterface( $domain['notes'] ) ); if ( $showManageActions ) { + if ( isset( $domain['addedBy'] ) ) { + $addedBy = $this->getLinkRenderer()->makeLink( + new TitleValue( 3, $domain['addedBy'] ), + $domain['addedBy'] + ); + } else { + $addedBy = ''; + } + $newRow .= Html::rawElement( 'td', [], $addedBy ); + $actionLink = $this->getLinkRenderer()->makeKnownLink( $this->getPageTitle( 'remove' ), $this->msg( 'abusefilter-blocked-domains-remove' )->text(),