Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1af68db747 | |||
| 80f28e5920 | |||
| 27d39a9d4a | |||
| e5b1669d53 | |||
| d3c49f1123 | |||
| 5ea635fd9a | |||
| 4304818bdb | |||
| 3fb4b609d4 | |||
| 83deddd7ee | |||
| 160a512d67 | |||
| f4dc6960bb | |||
| c24fee7a66 | |||
| 1e962c55fb | |||
| 0a6992b13b | |||
| 95567934b0 | |||
| 5e04b3afda | |||
| 91610c72fd | |||
| f1cae6b097 | |||
| 1a9cbbf48f | |||
| df0b14017b | |||
| ffc78324ff | |||
| 5a303252e3 | |||
| 4ec63619f5 | |||
| 572d9e3d87 | |||
| 3eb34310ef | |||
| 7c20f06902 | |||
| 144499a248 | |||
| 079e688ee9 | |||
| fb6e0f7755 | |||
| 4e17d17de6 | |||
| f3b2531380 | |||
| 536a4afe13 | |||
| b3648a462c |
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Jayden Bailey
|
||||
Copyright (c) 2021 Jayden Bailey
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
> ⚠️ **This branch is no longer maintained.** MediaWiki 1.36 went End-of-Life in June 2022.
|
||||
|
||||
# Discord (mw-discord)
|
||||
MediaWiki extension for sending notifications to a Discord webhook from MediaWiki. When a certain event occurs on your MediaWiki wiki, including new edits, they can be sent as a message to a channel on a Discord server using a webhook.
|
||||
|
||||
@@ -11,14 +13,14 @@ Multiple webhook URLs are supported and messages will be sent to all of them.
|
||||
|
||||
## Requirements
|
||||
- **Discord webhook URL**: This can be obtained by editing a channel on a server with the correct permissions.
|
||||
- **MediaWiki 1.31+**
|
||||
- **MediaWiki 1.36+**. This extension aims to support the latest LTS release. **Ensure you are using the correct branch of this extension for your MediaWiki version. The `master` branch includes changes only applicable for the latest MediaWiki version.**
|
||||
|
||||
### Recommended
|
||||
- **cURL**: By default, this extension sends requests using cURL. If you don't have cURL, you could try setting `$wgDiscordUseFileGetContents` to `true` instead, but this is not recommended.
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone this repository to your MediaWiki installation's `extensions` folder using `git clone https://github.com/jaydenkieran/mw-discord.git Discord`
|
||||
1. Clone this repository to your MediaWiki installation's `extensions` folder using `git clone https://github.com/jaydenkieran/mw-discord.git -b REL1_35 Discord`
|
||||
2. Modify your `LocalSettings.php` file and add:
|
||||
|
||||
```php
|
||||
@@ -48,19 +50,22 @@ This extension can be configured using the `LocalSettings.php` file in your Medi
|
||||
| `$wgDiscordNoNull` | bool | Do not send notifications for [null edits](https://www.mediawiki.org/wiki/Manual:Purge#Null_edits) | `true`
|
||||
| `$wgDiscordSuppressPreviews` | bool | Force previews for links in Discord messages to be suppressed | `true`
|
||||
| `$wgDiscordMaxChars` | int | Maximum amount of characters for user-generated text (e.g summaries, reasons). Set to `null` to disable truncation | `null`
|
||||
| `$wgDiscordMaxCharsUsernames` | int | Maximum amount of characters for usernames. Set to `null` to disable truncation | `25`
|
||||
| `$wgDiscordDisabledHooks` | array | List of hooks to disable sending webhooks for (see [below](#hooks-used)) | `[]`
|
||||
| `$wgDiscordDisabledNS` | array | List of namespaces to disable sending webhooks for | `[]`
|
||||
| `$wgDiscordDisabledUsers` | array | List of users whose performed actions shouldn't send webhooks | `[]`
|
||||
| `$wgDiscordPrependTimestamp` | bool | Prepend a timestamp (in UTC) to all sent messages. The format can be changed by editing the MediaWiki message `discord-timestampformat` | `false`
|
||||
| `$wgDiscordUseFileGetContents` | bool | Use `file_get_contents` instead of cURL. Requires `allow_url_fopen` to be set to true in `php.ini`. Not recommended as cURL makes simultaneous calls instead. | `false`
|
||||
| `$wgDiscordUseEmojis` | bool | Prepend emojis to different types of messages to help distinguish them | `false`
|
||||
| `$wgDiscordEmojis` | array | Map of hook names and their associated emojis to prepend to messages if `$wgDiscordUseEmojis` is enabled | See [extension.json](/extension.json)
|
||||
|
||||
## Hooks used
|
||||
- `PageContentSaveComplete` - New edits to pages and page creations
|
||||
- `PageSaveComplete` - New edits to pages and page creations
|
||||
- `ArticleDeleteComplete` - Page deletions
|
||||
- `ArticleUndelete` - Page restorations
|
||||
- `ArticleRevisionVisibilitySet` - Revision visibility changes
|
||||
- `ArticleProtectComplete` - Page protections
|
||||
- `TitleMoveComplete` - Page moves
|
||||
- `PageMoveComplete` - Page moves
|
||||
- `LocalUserCreated` - User registrations
|
||||
- `BlockIpComplete` - User blocked
|
||||
- `UnblockUserComplete` - User unblocked
|
||||
@@ -69,6 +74,13 @@ This extension can be configured using the `LocalSettings.php` file in your Medi
|
||||
- `FileDeleteComplete` - File revision was deleted
|
||||
- `FileUndeleteComplete` - File revision was restored
|
||||
- `AfterImportPage` - Page was imported
|
||||
- `ArticleMergeComplete` - Article histories was merged
|
||||
|
||||
### [Approved Revs](https://www.mediawiki.org/wiki/Extension:Approved_Revs)
|
||||
- `ApprovedRevsRevisionApproved` - Revision was approved
|
||||
- `ApprovedRevsRevisionUnapproved` - Revision was unapproved
|
||||
- `ApprovedRevsFileRevisionApproved` - File revision was approved
|
||||
- `ApprovedRevsFileRevisionUnapproved` - File revision was unapproved
|
||||
|
||||
## Translation
|
||||
This extension can be translated through the messages in the `ì18n` folder if you're a developer. As a wiki administrator, you may find it a better option to edit the messages on-site in the MediaWiki namespace.
|
||||
@@ -76,4 +88,4 @@ This extension can be translated through the messages in the `ì18n` folder if y
|
||||
Any excess whitespace in text that is translated will be stripped (e.g double spaces, etc).
|
||||
|
||||
## License
|
||||
This extension is licensed under the MIT License, [see here](LICENSE) for more information. This project is originally inspired by Szmyk's [mediawiki-discord](https://github.com/Szmyk/mediawiki-discord) project, but has been rewritten completely to be more suitable for my needs.
|
||||
This extension is licensed under the MIT License, [see here](LICENSE) for more information. This project is originally inspired by Szmyk's [mediawiki-discord](https://github.com/Szmyk/mediawiki-discord) project, but has been rewritten completely to be more suitable for my needs.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"require": {
|
||||
"phpunit/phpunit": "4.8.*"
|
||||
}
|
||||
}
|
||||
+37
-5
@@ -4,9 +4,12 @@
|
||||
"[https://github.com/jaydenkieran Jayden Bailey]"
|
||||
],
|
||||
"url": "https://github.com/jaydenkieran/mw-discord",
|
||||
"version": "1.0.10",
|
||||
"version": "1.0.12",
|
||||
"descriptionmsg": "discord-desc",
|
||||
"license-name": "MIT",
|
||||
"requires": {
|
||||
"MediaWiki": ">= 1.36.0"
|
||||
},
|
||||
"manifest_version": 1,
|
||||
"config": {
|
||||
"DiscordWebhookURL": [],
|
||||
@@ -15,11 +18,34 @@
|
||||
"DiscordNoNull": true,
|
||||
"DiscordSuppressPreviews": true,
|
||||
"DiscordMaxChars": null,
|
||||
"DiscordMaxCharsUsernames": 25,
|
||||
"DiscordDisabledHooks": [],
|
||||
"DiscordDisabledNS": [],
|
||||
"DiscordDisabledUsers": [],
|
||||
"DiscordPrependTimestamp": false,
|
||||
"DiscordUseFileGetContents": false
|
||||
"DiscordUseFileGetContents": false,
|
||||
"DiscordUseEmojis": false,
|
||||
"DiscordEmojis": {
|
||||
"PageContentSaveComplete": ":pencil2:",
|
||||
"ArticleDeleteComplete": ":wastebasket:",
|
||||
"ArticleUndelete": ":wastebasket:",
|
||||
"ArticleRevisionVisibilitySet": ":spy:",
|
||||
"ArticleProtectComplete": ":lock:",
|
||||
"TitleMoveComplete": ":truck:",
|
||||
"LocalUserCreated": ":wave:",
|
||||
"BlockIpComplete": ":no_entry_sign:",
|
||||
"UnblockUserComplete": ":no_entry_sign:",
|
||||
"UserGroupsChanged": ":people_holding_hands:",
|
||||
"UploadComplete": ":inbox_tray:",
|
||||
"FileDeleteComplete": ":wastebasket:",
|
||||
"FileUndeleteComplete": ":wastebasket:",
|
||||
"AfterImportPage": ":books:",
|
||||
"ArticleMergeComplete": ":card_box:",
|
||||
"ApprovedRevsRevisionApproved": ":white_check_mark:",
|
||||
"ApprovedRevsRevisionUnapproved": ":white_check_mark:",
|
||||
"ApprovedRevsFileRevisionApproved": ":white_check_mark:",
|
||||
"ApprovedRevsFileRevisionUnapproved": ":white_check_mark:"
|
||||
}
|
||||
},
|
||||
"AutoloadClasses": {
|
||||
"DiscordHooks": "src/DiscordHooks.php",
|
||||
@@ -29,12 +55,12 @@
|
||||
"mw-discord": "i18n"
|
||||
},
|
||||
"Hooks": {
|
||||
"PageContentSaveComplete": "DiscordHooks::onPageContentSaveComplete",
|
||||
"PageSaveComplete": "DiscordHooks::onPageSaveComplete",
|
||||
"ArticleDeleteComplete": "DiscordHooks::onArticleDeleteComplete",
|
||||
"ArticleUndelete": "DiscordHooks::onArticleUndelete",
|
||||
"ArticleRevisionVisibilitySet": "DiscordHooks::onArticleRevisionVisibilitySet",
|
||||
"ArticleProtectComplete": "DiscordHooks::onArticleProtectComplete",
|
||||
"TitleMoveComplete": "DiscordHooks::onTitleMoveComplete",
|
||||
"PageMoveComplete": "DiscordHooks::onPageMoveComplete",
|
||||
"LocalUserCreated": "DiscordHooks::onLocalUserCreated",
|
||||
"BlockIpComplete": "DiscordHooks::onBlockIpComplete",
|
||||
"UnblockUserComplete": "DiscordHooks::onUnblockUserComplete",
|
||||
@@ -42,6 +68,12 @@
|
||||
"UploadComplete": "DiscordHooks::onUploadComplete",
|
||||
"FileDeleteComplete": "DiscordHooks::onFileDeleteComplete",
|
||||
"FileUndeleteComplete": "DiscordHooks::onFileUndeleteComplete",
|
||||
"AfterImportPage": "DiscordHooks::onAfterImportPage"
|
||||
"AfterImportPage": "DiscordHooks::onAfterImportPage",
|
||||
"ArticleMergeComplete": "DiscordHooks::onArticleMergeComplete",
|
||||
"ApprovedRevsRevisionApproved": "DiscordHooks::onApprovedRevsRevisionApproved",
|
||||
"ApprovedRevsRevisionUnapproved": "DiscordHooks::onApprovedRevsRevisionUnapproved",
|
||||
"ApprovedRevsFileRevisionApproved": "DiscordHooks::onApprovedRevsFileRevisionApproved",
|
||||
"ApprovedRevsFileRevisionUnapproved": "DiscordHooks::onApprovedRevsFileRevisionUnapproved",
|
||||
"RenameUserComplete": "DiscordHooks::onRenameUserComplete"
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -30,5 +30,11 @@
|
||||
"discord-filedeletecomplete": "$1 deleted a version of file $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 restored some versions of file $2 $3",
|
||||
"discord-afterimportpage": "$1 imported $2 (imported $4/$3 revisions)",
|
||||
"discord-timestampformat": "**H:i e:**"
|
||||
"discord-timestampformat": "**H:i e:**",
|
||||
"discord-articlemergecomplete": "$1 merged revisions from $2 into $3",
|
||||
"discord-approvedrevsrevisionapproved": "$1 approved a new revision of $2 (revision $3) from user $4",
|
||||
"discord-approvedrevsrevisionunapproved": "$1 unapproved the approved revision for $2",
|
||||
"discord-approvedrevsfilerevisionapproved": "$1 approved a new file revision of $2 ($3) from user $4",
|
||||
"discord-approvedrevsfilerevisionunapproved": "$1 unapproved the approved file revision for $2",
|
||||
"discord-renameusercomplete": "$1 renamed the user $2 to $3"
|
||||
}
|
||||
|
||||
+7
-1
@@ -30,5 +30,11 @@
|
||||
"discord-filedeletecomplete": "Message sent to Discord when a file version is deleted (not an entire file). Parameters:\n$1 - discord-userlinks\n$2 - File link\n$3 - Comment (always surrounded in tildes)",
|
||||
"discord-fileundeletecomplete": "Message sent to Discord when a file version is restored (not an entire file). Parameters:\n$1 - discord-userlinks\n$2 - File link\n$3 - Comment (always surrounded in tildes)",
|
||||
"discord-afterimportpage": "Message sent to Discord when a page is imported. Parameters:\n$1 - discord-userlinks\n$2 - Page link\n$3 - Number of revisions in XML file\n$4 - Number of revisions successfully imported",
|
||||
"discord-timestampformat": "The formatting used in the gmtime() function for displaying the time an event happened in UTC."
|
||||
"discord-timestampformat": "The formatting used in the gmtime() function for displaying the time an event happened in UTC.",
|
||||
"discord-articlemergecomplete": "Message sent to Discord when page histories are merged. Parameters:\n$1 - discord-userlinks\n$2 - Target link\n$3 - Destination link",
|
||||
"discord-approvedrevsrevisionapproved": "Message sent to Discord when a revision is approved (Approved Revs extension). Parameters:\n$1 - discord-userlinks (admin user)\n$2 - Target link\n$3 - Revision link or ID\n$4 - discord-userlinks (revision author) or ID",
|
||||
"discord-approvedrevsrevisionunapproved": "Message sent to Discord when a revision is unapproved (Approved Revs extension). Parameters:\n$1 - discord-userlinks (admin user)\n$2 - Target link",
|
||||
"discord-approvedrevsfilerevisionapproved": "Message sent to Discord when a file revision is approved (Approved Revs extension). Parameters:\n$1 - discord-userlinks (admin user)\n$2 - Target link\n$3 - SHA of uploaded file\n$4 - discord-userlinks (revision author)",
|
||||
"discord-approvedrevsfilerevisionunapproved": "Message sent to Discord when a file revision is unapproved (Approved Revs extension). Parameters:\n$1 - discord-userlinks (admin user)\n$2 - Target link",
|
||||
"discord-renameusercomplete": "Message sent to Discord when a user is renamed (Renameuser extension). \n$1 - discord-userlinks (admin user)\n$2 - Old username\n$3 - New username link"
|
||||
}
|
||||
|
||||
+264
-68
@@ -1,4 +1,11 @@
|
||||
<?php
|
||||
|
||||
use MediaWiki\Linker\LinkTarget;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Revision\RevisionRecord;
|
||||
use MediaWiki\Storage\EditResult;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
|
||||
/**
|
||||
* Hooks for the Discord extension
|
||||
*
|
||||
@@ -8,12 +15,14 @@
|
||||
class DiscordHooks {
|
||||
/**
|
||||
* Called when a page is created or edited
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/PageContentSaveComplete
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/PageSaveComplete
|
||||
*/
|
||||
public static function onPageContentSaveComplete( &$wikiPage, &$user, $content, $summary, $isMinor, $isWatch, $section, &$flags, $revision, &$status, $baseRevId, $undidRevId ) {
|
||||
public static function onPageSaveComplete( WikiPage $wikiPage, UserIdentity $userIdentity, string $summary, int $flags, RevisionRecord $revision, EditResult $editResult ) {
|
||||
global $wgDiscordNoBots, $wgDiscordNoMinor, $wgDiscordNoNull;
|
||||
$hookName = 'PageContentSaveComplete';
|
||||
$user = User::newFromIdentity( $userIdentity );
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'PageContentSaveComplete', $wikiPage->getTitle()->getNamespace(), $user ) ) {
|
||||
if ( DiscordUtils::isDisabled( $hookName, $wikiPage->getTitle()->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -22,33 +31,32 @@ class DiscordHooks {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoMinor && $isMinor ) {
|
||||
if ( $wgDiscordNoMinor && $revision->isMinor() ) {
|
||||
// Don't continue, this is a minor edit
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoNull && ( !$revision || is_null( $status->getValue()['revision'] ) ) ) {
|
||||
if ( $wgDiscordNoNull && $editResult->isNullEdit() ) {
|
||||
// Don't continue, this is a null edit
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wikiPage->getTitle()->inNamespace( NS_FILE ) && is_null( $revision->getPrevious() ) ) {
|
||||
$isNew = $editResult->isNew();
|
||||
if ( $wikiPage->getTitle()->inNamespace( NS_FILE ) && $isNew ) {
|
||||
// Don't continue, it's a new file which onUploadComplete will handle instead
|
||||
return true;
|
||||
}
|
||||
|
||||
$msgKey = 'discord-edit';
|
||||
|
||||
$isNew = $status->value['new'];
|
||||
if ($isNew == 1) { // is a new page
|
||||
if ( $isNew ) { // is a new page
|
||||
$msgKey = 'discord-create';
|
||||
}
|
||||
|
||||
$msg = wfMessage( $msgKey, DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $wikiPage->getTitle(), $wikiPage->getTitle()->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
DiscordUtils::createMarkdownLink( $wikiPage->getTitle(), $wikiPage->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
DiscordUtils::createRevisionText( $revision ),
|
||||
( $summary ? ('`' . DiscordUtils::truncateText( $summary ) . '`' ) : '' ) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
( $summary ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $summary ) ) . '`' ) : '' ) )->plain();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -58,8 +66,9 @@ class DiscordHooks {
|
||||
*/
|
||||
public static function onArticleDeleteComplete( &$article, User &$user, $reason, $id, $content, LogEntry $logEntry, $archivedRevisionCount ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'ArticleDeleteComplete';
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'ArticleDeleteComplete', $article->getTitle()->getNamespace(), $user ) ) {
|
||||
if ( DiscordUtils::isDisabled( $hookName, $article->getTitle()->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -69,10 +78,10 @@ class DiscordHooks {
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-articledelete', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $article->getTitle(), $article->getTitle()->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ),
|
||||
DiscordUtils::createMarkdownLink( $article->getTitle(), $article->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
( $reason ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $reason ) ) . '`' ) : '' ),
|
||||
$archivedRevisionCount)->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -81,22 +90,25 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleUndelete
|
||||
*/
|
||||
public static function onArticleUndelete( Title $title, $create, $comment, $oldPageId, $restoredPages ) {
|
||||
global $wgDiscordNoBots, $wgUser;
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'ArticleUndelete';
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'ArticleUndelete', $title->getNamespace(), $wgUser ) ) {
|
||||
$user = RequestContext::getMain()->getUser();
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $wgUser->isBot() ) {
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot change
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-articleundelete', DiscordUtils::createUserLinks( $wgUser ),
|
||||
$msg = wfMessage( 'discord-articleundelete', DiscordUtils::createUserLinks( $user ),
|
||||
($create ? '' : wfMessage( 'discord-undeleterev' )->text() ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
( $comment ? ('`' . DiscordUtils::truncateText( $comment ) . '`' ) : '' ))->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
( $comment ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $comment ) ) . '`' ) : '' ))->plain();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -105,21 +117,24 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleRevisionVisibilitySet
|
||||
*/
|
||||
public static function onArticleRevisionVisibilitySet( &$title, $ids, $visibilityChangeMap ) {
|
||||
global $wgDiscordNoBots, $wgUser;
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'ArticleRevisionVisibilitySet';
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'ArticleRevisionVisibilitySet', $title->getNamespace(), $wgUser ) ) {
|
||||
$user = RequestContext::getMain()->getUser();
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $wgUser->isBot() ) {
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot change
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-revvisibility', DiscordUtils::createUserLinks( $wgUser ),
|
||||
$msg = wfMessage( 'discord-revvisibility', DiscordUtils::createUserLinks( $user ),
|
||||
count($visibilityChangeMap),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ) )->plain();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -129,8 +144,9 @@ class DiscordHooks {
|
||||
*/
|
||||
public static function onArticleProtectComplete( &$article, &$user, $protect, $reason ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'ArticleProtectComplete';
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'ArticleProtectComplete', $article->getTitle()->getNamespace(), $user ) ) {
|
||||
if ( DiscordUtils::isDisabled( $hookName, $article->getTitle()->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -140,21 +156,23 @@ class DiscordHooks {
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-articleprotect', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $article->getTitle(), $article->getTitle()->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ),
|
||||
DiscordUtils::createMarkdownLink( $article->getTitle(), $article->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
( $reason ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $reason ) ) . '`' ) : '' ),
|
||||
implode(", ", $protect) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a page is moved
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/TitleMoveComplete
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/PageMoveComplete
|
||||
*/
|
||||
public static function onTitleMoveComplete( Title &$title, Title &$newTitle, User $user, $oldid, $newid, $reason, Revision $revision ) {
|
||||
public static function onPageMoveComplete( LinkTarget $old, LinkTarget $new, UserIdentity $userIdentity, int $pageid, int $redirid, string $reason, RevisionRecord $revision ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'TitleMoveComplete';
|
||||
$user = User::newFromIdentity( $userIdentity );
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'TitleMoveComplete', $title->getNamespace(), $user ) ) {
|
||||
if ( DiscordUtils::isDisabled( $hookName, $old->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -164,11 +182,11 @@ class DiscordHooks {
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-titlemove', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
DiscordUtils::createMarkdownLink( $newTitle, $newTitle->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ),
|
||||
DiscordUtils::createMarkdownLink( $old, Title::castFromLinkTarget( $old )->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
DiscordUtils::createMarkdownLink( $new, Title::castFromLinkTarget( $new )->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
( $reason ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $reason ) ) . '`' ) : '' ),
|
||||
DiscordUtils::createRevisionText( $revision ) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -177,12 +195,14 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/LocalUserCreated
|
||||
*/
|
||||
public static function onLocalUserCreated( $user, $autocreated ) {
|
||||
if ( DiscordUtils::isDisabled( 'LocalUserCreated', NULL, $user ) ) {
|
||||
$hookName = 'LocalUserCreated';
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, NULL, $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-localusercreated', DiscordUtils::createUserLinks( $user ) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -191,7 +211,9 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/BlockIpComplete
|
||||
*/
|
||||
public static function onBlockIpComplete( Block $block, User $user ) {
|
||||
if ( DiscordUtils::isDisabled( 'BlockIpComplete', NULL, $user ) ) {
|
||||
$hookName = 'BlockIpComplete';
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, NULL, $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -203,9 +225,9 @@ class DiscordHooks {
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-blockipcomplete', DiscordUtils::createUserLinks( $user ), DiscordUtils::createUserLinks( $block->getTarget() ),
|
||||
( $block->mReason ? ('`' . DiscordUtils::truncateText( $block->mReason ) . '`' ) : '' ),
|
||||
( $block->getReasonComment()->text ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $block->getReasonComment()->text ) ) . '`' ) : '' ),
|
||||
$expiryMsg )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -214,12 +236,14 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/UnblockUserComplete
|
||||
*/
|
||||
public static function onUnblockUserComplete( Block $block, User $user ) {
|
||||
if ( DiscordUtils::isDisabled( 'UnblockUserComplete', NULL, $user ) ) {
|
||||
$hookName = 'UnblockUserComplete';
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, NULL, $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-unblockusercomplete', DiscordUtils::createUserLinks( $user ), DiscordUtils::createUserLinks( $block->getTarget() ) )->text();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -228,7 +252,9 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/UserGroupsChanged
|
||||
*/
|
||||
public static function onUserGroupsChanged( User $user, array $added, array $removed, $performer, $reason ) {
|
||||
if ( DiscordUtils::isDisabled( 'UserGroupsChanged', NULL, $performer ) ) {
|
||||
$hookName = 'UserGroupsChanged';
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, NULL, $performer ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -239,10 +265,10 @@ class DiscordHooks {
|
||||
|
||||
$msg = wfMessage( 'discord-usergroupschanged', DiscordUtils::createUserLinks( $performer ),
|
||||
DiscordUtils::createUserLinks( $user ),
|
||||
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ),
|
||||
( $reason ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $reason ) ) . '`' ) : '' ),
|
||||
( ( count($added) > 0 ) ? ( '+ ' . join(', ', $added) ) : ''),
|
||||
( ( count($removed) > 0 ) ? ( '- ' . join(', ', $removed) ) : '' ) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -252,11 +278,12 @@ class DiscordHooks {
|
||||
*/
|
||||
public static function onUploadComplete( &$image ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'UploadComplete';
|
||||
|
||||
$lf = $image->getLocalFile();
|
||||
$user = $lf->getUser( $type = 'object' ); // only supported in MW 1.31+
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'UploadComplete', NS_FILE, $user ) ) {
|
||||
if ( DiscordUtils::isDisabled( $hookName, NS_FILE, $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -270,13 +297,13 @@ class DiscordHooks {
|
||||
|
||||
$msg = wfMessage( 'discord-uploadcomplete', DiscordUtils::createUserLinks( $user ),
|
||||
( $isNewRevision ? wfMessage( 'discord-uploadnewver' )->text() : '' ),
|
||||
DiscordUtils::createMarkdownLink( $lf->getName(), $lf->getTitle()->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
( $comment ? ('`' . DiscordUtils::truncateText( $comment ) . '`' ) : '' ),
|
||||
DiscordUtils::createMarkdownLink( $lf->getName(), $lf->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
( $comment ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $comment ) ) . '`' ) : '' ),
|
||||
DiscordUtils::formatBytes($lf->getSize()),
|
||||
$lf->getWidth(),
|
||||
$lf->getHeight(),
|
||||
$lf->getMimeType() )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -286,8 +313,9 @@ class DiscordHooks {
|
||||
*/
|
||||
public static function onFileDeleteComplete( $file, $oldimage, $article, $user, $reason ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'FileDeleteComplete';
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'FileDeleteComplete', NS_FILE, $user ) ) {
|
||||
if ( DiscordUtils::isDisabled( $hookName, NS_FILE, $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -302,9 +330,9 @@ class DiscordHooks {
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-filedeletecomplete', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $file->getName(), $file->getTitle()->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::createMarkdownLink( $file->getName(), $file->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
( $reason ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $reason ) ) . '`' ) : '' ) )->plain();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -314,8 +342,9 @@ class DiscordHooks {
|
||||
*/
|
||||
public static function onFileUndeleteComplete( $title, $fileVersions, $user, $reason ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'FileUndeleteComplete';
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'FileUndeleteComplete', NS_FILE, $user ) ) {
|
||||
if ( DiscordUtils::isDisabled( $hookName, NS_FILE, $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -325,9 +354,9 @@ class DiscordHooks {
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-fileundeletecomplete', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
( $reason ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $reason ) ) . '`' ) : '' ) )->plain();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -336,21 +365,188 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/AfterImportPage
|
||||
*/
|
||||
public static function onAfterImportPage( $title, $origTitle, $revCount, $sRevCount, $pageInfo ) {
|
||||
global $wgDiscordNoBots, $wgUser;
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'AfterImportPage';
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'AfterImportPage', $title->getNamespace(), $wgUser ) ) {
|
||||
$user = RequestContext::getMain()->getUser();
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $wgUser->isBot() ) {
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-afterimportpage', DiscordUtils::createUserLinks( $wgUser ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
$msg = wfMessage( 'discord-afterimportpage', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
$revCount, $sRevCount)->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function onArticleMergeComplete( $targetTitle, $destTitle ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'ArticleMergeComplete';
|
||||
|
||||
$user = RequestContext::getMain()->getUser();
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, $destTitle->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-articlemergecomplete', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $targetTitle, $targetTitle->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
DiscordUtils::createMarkdownLink( $destTitle, $destTitle->getFullURL( '', false, PROTO_CANONICAL ) ))->plain();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a revision is approved (Approved Revs extension)
|
||||
* @see https://github.com/wikimedia/mediawiki-extensions-ApprovedRevs/blob/REL1_34/includes/ApprovedRevs_body.php
|
||||
*/
|
||||
public static function onApprovedRevsRevisionApproved ( $output, $title, $rev_id, $content ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'ApprovedRevsRevisionApproved';
|
||||
|
||||
$user = RequestContext::getMain()->getUser();
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the revision being approved here
|
||||
$rev = MediaWikiServices::getInstance()->getRevisionLookup()->getRevisionByTitle( $title, $rev_id );
|
||||
$revLink = $title->getFullURL( '', false, PROTO_CANONICAL );
|
||||
$revAuthor = DiscordUtils::createUserLinks( $rev->getUser( RevisionRecord::RAW ) );
|
||||
|
||||
$msg = wfMessage( 'discord-approvedrevsrevisionapproved', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
DiscordUtils::createMarkdownLink( $rev_id, $revLink ),
|
||||
$revAuthor)->plain();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a revision is unapproved (Approved Revs extension)
|
||||
* @see https://github.com/wikimedia/mediawiki-extensions-ApprovedRevs/blob/REL1_34/includes/ApprovedRevs_body.php
|
||||
*/
|
||||
public static function onApprovedRevsRevisionUnapproved ( $output, $title, $content ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'ApprovedRevsRevisionUnapproved';
|
||||
|
||||
$user = RequestContext::getMain()->getUser();
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-approvedrevsrevisionunapproved', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ) )->plain();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a file is approved (Approved Revs extension)
|
||||
* @see https://github.com/wikimedia/mediawiki-extensions-ApprovedRevs/blob/REL1_34/includes/ApprovedRevs_body.php
|
||||
*/
|
||||
public static function onApprovedRevsFileRevisionApproved ( $parser, $title, $timestamp, $sha1 ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'ApprovedRevsFileRevisionApproved';
|
||||
|
||||
$user = RequestContext::getMain()->getUser();
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot
|
||||
return true;
|
||||
}
|
||||
|
||||
$imagepage = ImagePage::newFromID( $title->getArticleID() );
|
||||
$displayedFile = $imagepage->getDisplayedFile();
|
||||
$displayedFileUrl = $displayedFile->getCanonicalUrl(); // getFullURL doesn't work quite the same on File classes
|
||||
$uploader = $displayedFile->getUser();
|
||||
|
||||
if (is_string($uploader)) {
|
||||
$uploader = User::newFromName($uploader, false);
|
||||
} else {
|
||||
$uploader = User::newFromId($uploader);
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-approvedrevsfilerevisionapproved', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
DiscordUtils::createMarkdownLink( 'direct', $displayedFileUrl ),
|
||||
DiscordUtils::createUserLinks( $uploader ) )->plain();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a file is unapproved (Approved Revs extension)
|
||||
* @see https://github.com/wikimedia/mediawiki-extensions-ApprovedRevs/blob/REL1_34/includes/ApprovedRevs_body.php
|
||||
*/
|
||||
public static function onApprovedRevsFileRevisionUnapproved ( $parser, $title ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'ApprovedRevsFileRevisionUnapproved';
|
||||
|
||||
$user = RequestContext::getMain()->getUser();
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-approvedrevsfilerevisionunapproved', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ) )->plain();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a user is renamed (Renameuser extension)
|
||||
* @see https://github.com/wikimedia/mediawiki-extensions-Renameuser/blob/REL1_36/includes/RenameuserSQL.php
|
||||
*/
|
||||
public static function onRenameUserComplete ( $uid, $old, $new ) {
|
||||
$hookName = 'RenameUserComplete';
|
||||
|
||||
$user = RequestContext::getMain()->getUser();
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, null, null ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$renamedUserAsTitle = User::newFromName( $new )->getUserPage();
|
||||
|
||||
$msg = wfMessage( 'discord-renameusercomplete', DiscordUtils::createUserLinks( $user ),
|
||||
"*$old*",
|
||||
DiscordUtils::createMarkdownLink( $new, $renamedUserAsTitle->getFullURL( '', false, PROTO_CANONICAL ) ) )->plain();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+60
-31
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
class DiscordUtils {
|
||||
/**
|
||||
* Checks if criteria is met for this action to be cancelled
|
||||
@@ -45,8 +47,8 @@ class DiscordUtils {
|
||||
/**
|
||||
* Handles sending a webhook to Discord using cURL
|
||||
*/
|
||||
public static function handleDiscord ($msg) {
|
||||
global $wgDiscordWebhookURL, $wgDiscordPrependTimestamp, $wgDiscordUseFileGetContents;
|
||||
public static function handleDiscord ($hookName, $msg) {
|
||||
global $wgDiscordWebhookURL, $wgDiscordEmojis, $wgDiscordUseEmojis, $wgDiscordPrependTimestamp, $wgDiscordUseFileGetContents;
|
||||
|
||||
if ( !$wgDiscordWebhookURL ) {
|
||||
// There's nothing in here, so we won't do anything
|
||||
@@ -73,10 +75,21 @@ class DiscordUtils {
|
||||
$stripped = $dateString . ' ' . $stripped;
|
||||
}
|
||||
|
||||
if ( $wgDiscordUseEmojis ) {
|
||||
// Add emoji
|
||||
$emoji = $wgDiscordEmojis[$hookName];
|
||||
$stripped = $emoji . ' ' . $stripped;
|
||||
}
|
||||
|
||||
DeferredUpdates::addCallableUpdate( function() use ( $stripped, $urls, $wgDiscordUseFileGetContents ) {
|
||||
$user_agent = 'mw-discord/1.0 (github.com/jaydenkieran)';
|
||||
$json_data = [ 'content' => "$stripped" ];
|
||||
$json = json_encode($json_data);
|
||||
$json_data = [
|
||||
'content' => "$stripped",
|
||||
'allowed_mentions' => [
|
||||
'parse' => []
|
||||
]
|
||||
];
|
||||
$json = json_encode($json_data);
|
||||
|
||||
if ( $wgDiscordUseFileGetContents ) {
|
||||
// They want to use file_get_contents
|
||||
@@ -95,12 +108,12 @@ class DiscordUtils {
|
||||
$result = file_get_contents( $value, false, $context );
|
||||
}
|
||||
} else {
|
||||
// By default, we use cURL
|
||||
// By default, we use cURL
|
||||
// Set up cURL multi handlers
|
||||
$c_handlers = [];
|
||||
$result = [];
|
||||
$mh = curl_multi_init();
|
||||
|
||||
|
||||
foreach ($urls as &$value) {
|
||||
$c_handlers[$value] = curl_init( $value );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_POST, 1 ); // Send as a POST request
|
||||
@@ -116,19 +129,19 @@ class DiscordUtils {
|
||||
));
|
||||
curl_multi_add_handle( $mh, $c_handlers[$value] );
|
||||
}
|
||||
|
||||
|
||||
$running = null;
|
||||
do {
|
||||
curl_multi_exec($mh, $running);
|
||||
} while ($running);
|
||||
|
||||
|
||||
// Remove all handlers and then close the multi handler
|
||||
foreach($c_handlers as $k => $ch) {
|
||||
$result[$k] = curl_multi_getcontent($ch);
|
||||
wfDebugLog( 'discord', 'Result of cURL was: ' . $result[$k] );
|
||||
curl_multi_remove_handle($mh, $ch);
|
||||
}
|
||||
|
||||
|
||||
curl_multi_close($mh);
|
||||
}
|
||||
} );
|
||||
@@ -149,14 +162,24 @@ class DiscordUtils {
|
||||
* Creates links for a specific MediaWiki User object
|
||||
*/
|
||||
public static function createUserLinks ($user) {
|
||||
global $wgDiscordMaxCharsUsernames;
|
||||
|
||||
if ( $user instanceof User ) {
|
||||
$isAnon = $user->isAnon();
|
||||
$contribs = Title::newFromText("Special:Contributions/" . $user);
|
||||
|
||||
$userPage = DiscordUtils::createMarkdownLink( $user, ( $isAnon ? $contribs : $user->getUserPage() )->getFullUrl( '', '', $proto = PROTO_HTTP ) );
|
||||
$userTalk = DiscordUtils::createMarkdownLink( wfMessage( 'discord-talk' )->text(), $user->getTalkPage()->getFullUrl( '', '', $proto = PROTO_HTTP ) );
|
||||
$userContribs = DiscordUtils::createMarkdownLink( wfMessage( 'discord-contribs' )->text(), $contribs->getFullURL( '', '', $proto = PROTO_HTTP ) );
|
||||
$text = wfMessage( 'discord-userlinks', $userPage, $userTalk, $userContribs )->text();
|
||||
if ($wgDiscordMaxCharsUsernames) {
|
||||
$user_abbr = strval($user);
|
||||
if (strlen($user_abbr) > $wgDiscordMaxCharsUsernames) {
|
||||
$user_abbr = substr($user_abbr, 0, $wgDiscordMaxCharsUsernames);
|
||||
$user_abbr = $user_abbr.'...';
|
||||
}
|
||||
}
|
||||
|
||||
$userPage = DiscordUtils::createMarkdownLink( $user_abbr, ( $isAnon ? $contribs : $user->getUserPage() )->getFullURL( '', false, PROTO_CANONICAL ) );
|
||||
$userTalk = DiscordUtils::createMarkdownLink( wfMessage( 'discord-talk' )->text(), $user->getTalkPage()->getFullURL( '', false, PROTO_CANONICAL ) );
|
||||
$userContribs = DiscordUtils::createMarkdownLink( wfMessage( 'discord-contribs' )->text(), $contribs->getFullURL( '', false, PROTO_CANONICAL ) );
|
||||
$text = wfMessage( 'discord-userlinks', $userPage, $userTalk, $userContribs )->text();
|
||||
} else {
|
||||
// If it's a string, which can be likely (for example when range blocking a user)
|
||||
// We need to handle this differently.
|
||||
@@ -169,20 +192,17 @@ class DiscordUtils {
|
||||
* Creates formatted text for a specific Revision object
|
||||
*/
|
||||
public static function createRevisionText ($revision) {
|
||||
$diff = DiscordUtils::createMarkdownLink( wfMessage( 'discord-diff' )->text(), $revision->getTitle()->getFullUrl("diff=prev", ["oldid" => $revision->getID()], $proto = PROTO_HTTP) );
|
||||
$diff = DiscordUtils::createMarkdownLink( wfMessage( 'discord-diff' )->text(), $revision->getPageAsLinkTarget()->getFullURL( [ 'diff' => 'prev', 'oldid' => $revision->getId() ], false, PROTO_CANONICAL ) );
|
||||
$minor = '';
|
||||
$size = '';
|
||||
if ( $revision->isMinor() ) {
|
||||
$minor .= wfMessage( 'discord-minor' )->text();
|
||||
}
|
||||
$previous = $revision->getPrevious();
|
||||
if ( $previous ) {
|
||||
$size .= wfMessage( 'discord-size', sprintf( "%+d", $revision->getSize() - $previous->getSize() ) )->text();
|
||||
} else if ( $revision->getParentId() ) {
|
||||
// Try and get the parent revision based on the ID, if we can
|
||||
$previous = Revision::newFromId( $revision->getParentId() );
|
||||
if ($previous) {
|
||||
$size .= wfMessage( 'discord-size', sprintf( "%+d", $revision->getSize() - $previous->getSize() ) )->text();
|
||||
$parentId = $revision->getParentId();
|
||||
if ( $parentId ) {
|
||||
$parent = MediaWikiServices::getInstance()->getRevisionLookup()->getRevisionById( $parentId );
|
||||
if ( $parent ) {
|
||||
$size .= wfMessage( 'discord-size', sprintf( "%+d", $revision->getSize() - $parent->getSize() ) )->text();
|
||||
}
|
||||
}
|
||||
if ( $size == '' ) {
|
||||
@@ -191,7 +211,7 @@ class DiscordUtils {
|
||||
$text = wfMessage( 'discord-revisionlinks', $diff, $minor, $size )->text();
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Strip bad characters from a URL
|
||||
*/
|
||||
@@ -201,20 +221,20 @@ class DiscordUtils {
|
||||
$url = str_replace(")", "%29", $url);
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Formats bytes to a string representing B, KB, MB, GB, TB
|
||||
*/
|
||||
public static function formatBytes($bytes, $precision = 2) {
|
||||
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
||||
public static function formatBytes($bytes, $precision = 2) {
|
||||
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
||||
|
||||
$bytes = max($bytes, 0);
|
||||
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
||||
$pow = min($pow, count($units) - 1);
|
||||
$bytes = max($bytes, 0);
|
||||
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
||||
$pow = min($pow, count($units) - 1);
|
||||
|
||||
$bytes /= (1 << (10 * $pow));
|
||||
$bytes /= (1 << (10 * $pow));
|
||||
|
||||
return round($bytes, $precision) . ' ' . $units[$pow];
|
||||
return round($bytes, $precision) . ' ' . $units[$pow];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,6 +250,15 @@ class DiscordUtils {
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitise text input, including removing the potential for abuse
|
||||
* of Discord's @everyone and @here pings
|
||||
*/
|
||||
public static function sanitiseText($text) {
|
||||
$text = preg_replace('/(`|@)/', '', $text);
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user