Compare commits
67 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d5fab7c035 | |||
| cd8f91388a | |||
| 6c44fdeaf1 | |||
| 6b138edf84 | |||
| 367d50494b | |||
| 83e505d39b | |||
| 5bdc31f6e8 | |||
| 42f292f17f | |||
| 2a9a65a59a | |||
| 2a560d9acc | |||
| 0b91e8edc8 | |||
| 96070a6538 | |||
| 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 | |||
| bbff717a24 | |||
| 6d8b2c33cb | |||
| 47eef3c35d | |||
| 7f51c4f310 | |||
| ad101a326f | |||
| 687d1abf1f | |||
| 0df5463a87 | |||
| 10b4db72f7 | |||
| fb9ada8f9c | |||
| 9a7dd03d5c | |||
| fa9149165d | |||
| ca3a5f8047 | |||
| 591ef8746e | |||
| 6c2e30deab | |||
| ce780adf10 | |||
| 680040e823 | |||
| 8fa8dce03d | |||
| c3bdbecee5 | |||
| 6ccca7b823 | |||
| 03d612a3f7 | |||
| 9830df7e97 | |||
| cecb90dffc | |||
| 78d66e5e31 |
@@ -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,7 +1,9 @@
|
||||
> ⚠️ **This branch is no longer maintained.** MediaWiki 1.38 went End-of-Life in June 2023.
|
||||
|
||||
# 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.
|
||||
|
||||
Multiple webhook URLs are supported and messages will be sent to all of them using cURL, so your web server is required to have cURL installed (for most Linux distros, installing using `sudo apt install curl` should work).
|
||||
Multiple webhook URLs are supported and messages will be sent to all of them.
|
||||
|
||||
**Live demo**: https://runescape.wiki (https://discord.gg/runescapewiki)
|
||||
|
||||
@@ -11,12 +13,17 @@ Multiple webhook URLs are supported and messages will be sent to all of them usi
|
||||
|
||||
## Requirements
|
||||
- **Discord webhook URL**: This can be obtained by editing a channel on a server with the correct permissions.
|
||||
- **MediaWiki 1.31+**
|
||||
- **cURL**
|
||||
- **MediaWiki**: This extension aims to always support the [latest LTS release](https://www.mediawiki.org/wiki/Version_lifecycle).
|
||||
- Use the branch that is equal to, or below your version. For example, if you are using MediaWiki 1.37, use the `REL1_36` branch.
|
||||
- We do not guarantee support for versions of MediaWiki that are considered end-of-life.
|
||||
- The `master` branch may contain changes that are only applicable to the cutting-edge alpha version of MediaWiki.
|
||||
|
||||
### 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
|
||||
@@ -39,6 +46,8 @@ This extension can be configured using the `LocalSettings.php` file in your Medi
|
||||
| `$wgDiscordWebhookURL` | string/array | Discord webhook URLs
|
||||
|
||||
### Optional
|
||||
These parameters aren't required for the extension to work.
|
||||
|
||||
| Variable | Type | Description | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| `$wgDiscordNoBots` | bool | Do not send notifications that are triggered by a [bot account](https://www.mediawiki.org/wiki/Manual:Bots) | `true`
|
||||
@@ -46,17 +55,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
|
||||
- `ArticleDeleteComplete` - Page deletions
|
||||
- `PageSaveComplete` - New edits to pages and page creations
|
||||
- `PageDeleteComplete` - 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
|
||||
@@ -64,11 +78,22 @@ This extension can be configured using the `LocalSettings.php` file in your Medi
|
||||
- `UploadComplete` - File was uploaded
|
||||
- `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
|
||||
|
||||
### [Renameuser](https://www.mediawiki.org/wiki/Extension:Renameuser)
|
||||
- `RenameUserComplete` - Rename was completed
|
||||
|
||||
## 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.
|
||||
|
||||
Any excess whitespace in text that is translated will be stripped (e.g double spaces, etc).
|
||||
You can submit translations for this extension on [Translatewiki.net](https://translatewiki.net/wiki/Special:Translate/mwgithub-mw-discord).
|
||||
|
||||
## 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 available under the MIT license. You can [see here](LICENSE) for more information.
|
||||
|
||||
This extension was inspired by Szmyk's [mediawiki-discord](https://github.com/Szmyk/mediawiki-discord) project.
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"require": {
|
||||
"phpunit/phpunit": "4.8.*"
|
||||
}
|
||||
}
|
||||
+44
-8
@@ -1,12 +1,15 @@
|
||||
{
|
||||
"name": "Discord",
|
||||
"author": [
|
||||
"[https://github.com/jaydenkieran Jayden Bailey]"
|
||||
"[https://github.com/jayktaylor Jayden Bailey]"
|
||||
],
|
||||
"url": "https://github.com/jaydenkieran/mw-discord",
|
||||
"version": "1.0.4",
|
||||
"url": "https://github.com/jayktaylor/mw-discord",
|
||||
"version": "1.0.13",
|
||||
"descriptionmsg": "discord-desc",
|
||||
"license-name": "MIT",
|
||||
"requires": {
|
||||
"MediaWiki": ">= 1.38.0"
|
||||
},
|
||||
"manifest_version": 1,
|
||||
"config": {
|
||||
"DiscordWebhookURL": [],
|
||||
@@ -15,9 +18,35 @@
|
||||
"DiscordNoNull": true,
|
||||
"DiscordSuppressPreviews": true,
|
||||
"DiscordMaxChars": null,
|
||||
"DiscordMaxCharsUsernames": 25,
|
||||
"DiscordDisabledHooks": [],
|
||||
"DiscordDisabledNS": [],
|
||||
"DiscordDisabledUsers": []
|
||||
"DiscordDisabledUsers": [],
|
||||
"DiscordPrependTimestamp": false,
|
||||
"DiscordUseFileGetContents": false,
|
||||
"DiscordUseEmojis": false,
|
||||
"DiscordEmojis": {
|
||||
"PageSaveComplete": ":pencil2:",
|
||||
"PageDeleteComplete": ":wastebasket:",
|
||||
"ArticleUndelete": ":wastebasket:",
|
||||
"ArticleRevisionVisibilitySet": ":spy:",
|
||||
"ArticleProtectComplete": ":lock:",
|
||||
"PageMoveComplete": ":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:",
|
||||
"RenameUserComplete": ":people_holding_hands:"
|
||||
}
|
||||
},
|
||||
"AutoloadClasses": {
|
||||
"DiscordHooks": "src/DiscordHooks.php",
|
||||
@@ -27,18 +56,25 @@
|
||||
"mw-discord": "i18n"
|
||||
},
|
||||
"Hooks": {
|
||||
"PageContentSaveComplete": "DiscordHooks::onPageContentSaveComplete",
|
||||
"ArticleDeleteComplete": "DiscordHooks::onArticleDeleteComplete",
|
||||
"PageSaveComplete": "DiscordHooks::onPageSaveComplete",
|
||||
"PageDeleteComplete": "DiscordHooks::onPageDeleteComplete",
|
||||
"ArticleUndelete": "DiscordHooks::onArticleUndelete",
|
||||
"ArticleRevisionVisibilitySet": "DiscordHooks::onArticleRevisionVisibilitySet",
|
||||
"ArticleProtectComplete": "DiscordHooks::onArticleProtectComplete",
|
||||
"TitleMoveComplete": "DiscordHooks::onTitleMoveComplete",
|
||||
"PageMoveComplete": "DiscordHooks::onPageMoveComplete",
|
||||
"LocalUserCreated": "DiscordHooks::onLocalUserCreated",
|
||||
"BlockIpComplete": "DiscordHooks::onBlockIpComplete",
|
||||
"UnblockUserComplete": "DiscordHooks::onUnblockUserComplete",
|
||||
"UserGroupsChanged": "DiscordHooks::onUserGroupsChanged",
|
||||
"UploadComplete": "DiscordHooks::onUploadComplete",
|
||||
"FileDeleteComplete": "DiscordHooks::onFileDeleteComplete",
|
||||
"FileUndeleteComplete": "DiscordHooks::onFileUndeleteComplete"
|
||||
"FileUndeleteComplete": "DiscordHooks::onFileUndeleteComplete",
|
||||
"AfterImportPage": "DiscordHooks::onAfterImportPage",
|
||||
"ArticleMergeComplete": "DiscordHooks::onArticleMergeComplete",
|
||||
"ApprovedRevsRevisionApproved": "DiscordHooks::onApprovedRevsRevisionApproved",
|
||||
"ApprovedRevsRevisionUnapproved": "DiscordHooks::onApprovedRevsRevisionUnapproved",
|
||||
"ApprovedRevsFileRevisionApproved": "DiscordHooks::onApprovedRevsFileRevisionApproved",
|
||||
"ApprovedRevsFileRevisionUnapproved": "DiscordHooks::onApprovedRevsFileRevisionUnapproved",
|
||||
"RenameUserComplete": "DiscordHooks::onRenameUserComplete"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"আফতাবুজ্জামান"
|
||||
]
|
||||
},
|
||||
"discord-talk": "আ",
|
||||
"discord-contribs": "অ",
|
||||
"discord-diff": "পার্থক্য",
|
||||
"discord-minor": "(অ)",
|
||||
"discord-edit": "$1 $2 সম্পাদনা করেছেন $3 $4",
|
||||
"discord-create": "$1 $2 তৈরি করেছেন $3 $4",
|
||||
"discord-localusercreated": "$1 নিবন্ধিত হয়েছে",
|
||||
"discord-blockipcomplete": "$1 $2-কে বাধা দিয়েছেন $3 ($4)"
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Dogogos123"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Στέλνει μηνύματα σε ένα κανάλι Discord όταν συμβαίνουν ορισμένα συμβάντα",
|
||||
"discord-diff": "διαφορά",
|
||||
"discord-edit": "$1 επεξεργάστηκε $2 $3 $4.",
|
||||
"discord-create": "$1 δημιούργησε $2 $3 $4",
|
||||
"discord-articledelete": "$1 διαγράφηκε $2 $3 ($4 αναθεωρήσεις διαγράφηκαν)",
|
||||
"discord-undeleterev": "αναθεωρήσεις για",
|
||||
"discord-articleundelete": "$1 επανέφερε $2 $3 $4",
|
||||
"discord-revvisibility": "$1 άλλαξε την ορατότητα των $2 αναθεωρήσεων στο $3",
|
||||
"discord-articleprotect": "$1 άλλαξε προστασία του $2 $3 ( $4 )",
|
||||
"discord-titlemove": "$1 μετακίνησε $2 στα $3 $4 $5",
|
||||
"discord-localusercreated": "$1 εγγεγραμμένος",
|
||||
"discord-blockipcomplete": "$1 αποκλεισμένο $2 $3 ( $4 )",
|
||||
"discord-unblockusercomplete": "$1 ξεμπλόκαρε $2",
|
||||
"discord-usergroupschanged": "$1 άλλαξε τα δικαιώματα των $2 $3 ( $4 ) ( $5 )",
|
||||
"discord-uploadnewver": "νέα έκδοση του",
|
||||
"discord-uploadcomplete": "$1 μεταφορτώθηκε $2 $3 $4 ( $5 , $6 x $7 , $8 )",
|
||||
"discord-filedeletecomplete": "$1 διέγραψε μια έκδοση του αρχείου $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 επανέφερε ορισμένες εκδόσεις του αρχείου $2 $3",
|
||||
"discord-afterimportpage": "$1 εισήχθη $2 (εισαγμένες $4 / $3 αναθεωρήσεις)",
|
||||
"discord-articlemergecomplete": "$1 συγχώνευσε αναθεωρήσεις από $2 σε $3",
|
||||
"discord-approvedrevsrevisionapproved": "$1 ενέκρινε μια νέα αναθεώρηση των $2 (αναθεώρηση $3 ) από τον χρήστη $4",
|
||||
"discord-approvedrevsrevisionunapproved": "$1 κατάργησε την έγκριση της εγκεκριμένης αναθεώρησης του αρχείου για $2",
|
||||
"discord-approvedrevsfilerevisionapproved": "$1 ενέκρινε μια νέα αναθεώρηση αρχείου $2 ( $3 ) από τον χρήστη $4",
|
||||
"discord-approvedrevsfilerevisionunapproved": "$1 κατάργησε την έγκριση της εγκεκριμένης αναθεώρησης του αρχείου για $2",
|
||||
"discord-renameusercomplete": "$1 μετονόμασε τον χρήστη $2 σε $3"
|
||||
}
|
||||
+14
-1
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Jayden Bailey"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Sends messages to a Discord channel when certain events occur",
|
||||
"discord-userlinks": "$1 ($2|$3)",
|
||||
"discord-revisionlinks": "($1) $2 $3",
|
||||
@@ -23,5 +28,13 @@
|
||||
"discord-uploadnewver": "new version of",
|
||||
"discord-uploadcomplete": "$1 uploaded $2 $3 $4 ($5, $6x$7, $8)",
|
||||
"discord-filedeletecomplete": "$1 deleted a version of file $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 restored some versions 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-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"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Verdy p"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Envoie des messages à un canal Discord quand certains événements surviennent",
|
||||
"discord-userlinks": "$1 ($2|$3)",
|
||||
"discord-revisionlinks": "($1) $2 $3",
|
||||
"discord-talk": "t",
|
||||
"discord-contribs": "c",
|
||||
"discord-diff": "diff",
|
||||
"discord-minor": "(m)",
|
||||
"discord-size": "($1)",
|
||||
"discord-edit": "$1 a modifié $2 $3 : $4",
|
||||
"discord-create": "$1 a créé $2 $3 : $4",
|
||||
"discord-articledelete": "$1 a supprimé $2 ($4 version(s) supprimée(s)) : $3",
|
||||
"discord-undeleterev": "versions pour",
|
||||
"discord-articleundelete": "$1 a restauré $2 $3 : $4",
|
||||
"discord-revvisibility": "$1 a modifié la visibilité de $2 version(s) sur $3",
|
||||
"discord-articleprotect": "$1 a modifié la protection de $2 ($4) : $3",
|
||||
"discord-titlemove": "$1 a renommé $2 en $3 $5 : $4",
|
||||
"discord-localusercreated": "$1 s’est inscrit(e)",
|
||||
"discord-blocktimeformat": "d F Y H:i",
|
||||
"discord-blockipcomplete": "$1 a bloqué $2 ($4) : $3",
|
||||
"discord-unblockusercomplete": "$1 a débloqué $2",
|
||||
"discord-usergroupschanged": "$1 a modifié les droits de $2 ($4) ($5) : $3",
|
||||
"discord-uploadnewver": "nouvelle version de",
|
||||
"discord-uploadcomplete": "$1 a téléversé $2 $3 ($5, $6x$7, $8) : $4",
|
||||
"discord-filedeletecomplete": "$1 a supprimé une version du fichier $2 : $3",
|
||||
"discord-fileundeletecomplete": "$1 a restauré certaines versions du fichier $2 : $3",
|
||||
"discord-afterimportpage": "$1 a importé $2 ($4 / $3 révisions importées)",
|
||||
"discord-timestampformat": "**H:i e:**",
|
||||
"discord-articlemergecomplete": "$1 a fusionné des versions de $2 vers $3",
|
||||
"discord-approvedrevsrevisionapproved": "$1 a approuvé une nouvelle version de $2 (version $3) créée par $4",
|
||||
"discord-approvedrevsrevisionunapproved": "$1 a désapprouvé la version approuvée de $2",
|
||||
"discord-approvedrevsfilerevisionapproved": "$1 a approuvé une nouvelle version de fichier dans $2 ($3) créée par $4",
|
||||
"discord-approvedrevsfilerevisionunapproved": "$1 a désapprouvé la version de fichier approuvée dans $2",
|
||||
"discord-renameusercomplete": "$1 a renommé l’utilisateur ou l’utilisatrice $2 en $3"
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"McDutchie"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Invia messages a un canal Discord quando certe eventos occurre",
|
||||
"discord-talk": "t",
|
||||
"discord-contribs": "c",
|
||||
"discord-diff": "diff",
|
||||
"discord-minor": "(m)",
|
||||
"discord-edit": "$1 ha modificate $2 $3 $4",
|
||||
"discord-create": "$1 ha create $2 $3 $4",
|
||||
"discord-articledelete": "$1 ha delite $2 $3 ($4 versiones delite)",
|
||||
"discord-undeleterev": "versiones pro",
|
||||
"discord-articleundelete": "$1 ha restaurate $2 $3 $4",
|
||||
"discord-revvisibility": "$1 ha cambiate le visibilitate de of $2 versiones sur $3",
|
||||
"discord-articleprotect": "$1 ha cambiate le protection de $2 $3 ($4)",
|
||||
"discord-titlemove": "$1 ha renominate $2 a $3 $4 $5",
|
||||
"discord-localusercreated": "$1 se ha inscribite",
|
||||
"discord-blocktimeformat": "d F Y H:i",
|
||||
"discord-blockipcomplete": "$1 ha blocate $2 $3 ($4)",
|
||||
"discord-unblockusercomplete": "$1 ha disblocate $2",
|
||||
"discord-usergroupschanged": "$1 ha cambiate le derectos de $2 $3 ($4) ($5)",
|
||||
"discord-uploadnewver": "nove version de",
|
||||
"discord-uploadcomplete": "$1 ha incargate $2 $3 $4 ($5, $6x$7, $8)",
|
||||
"discord-filedeletecomplete": "$1 ha delite un version del file $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 ha restaurate alcun versiones del file $2 $3",
|
||||
"discord-afterimportpage": "$1 ha importate $2 ($4/$3 versiones importate)",
|
||||
"discord-timestampformat": "**H:i e:**",
|
||||
"discord-articlemergecomplete": "$1 ha fusionate le versiones de $2 in $3",
|
||||
"discord-approvedrevsrevisionapproved": "$1 ha approbate un nove version de $2 (version $3) del usator $4",
|
||||
"discord-approvedrevsrevisionunapproved": "$1 ha disapprobate le version approbate de $2",
|
||||
"discord-approvedrevsfilerevisionapproved": "$1 ha approbate un nove version del file $2 ($3) del usator $4",
|
||||
"discord-approvedrevsfilerevisionunapproved": "$1 ha disapprobate le version approbate del file $2",
|
||||
"discord-renameusercomplete": "$1 ha renominate le usator $2 a $3"
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Bjankuloski06"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Испраќа пораки на канал на Дискорд кога ќе се случат извесни настани",
|
||||
"discord-talk": "t",
|
||||
"discord-contribs": "c",
|
||||
"discord-diff": "разл",
|
||||
"discord-minor": "(м)",
|
||||
"discord-edit": "$1 уреди $2 $3 $4",
|
||||
"discord-create": "$1 создаде $2 $3 $4",
|
||||
"discord-articledelete": "$1 избриша $2 $3 (избришани $4 преработки)",
|
||||
"discord-undeleterev": "преработки за",
|
||||
"discord-articleundelete": "$1 поврати $2 $3 $4",
|
||||
"discord-revvisibility": "$1 смени видливост на $2 преработки на $3",
|
||||
"discord-articleprotect": "$1 смени заштита на $2 $3 ($4)",
|
||||
"discord-titlemove": "$1 премести $2 на $3 $4 $5",
|
||||
"discord-localusercreated": "$1 зачленети",
|
||||
"discord-blocktimeformat": "j F Y G:i ч.",
|
||||
"discord-blockipcomplete": "$1 блокираше $2 $3 ($4)",
|
||||
"discord-unblockusercomplete": "$1 одблокираше $2",
|
||||
"discord-usergroupschanged": "$1 ги смени правата на $2 $3 ($4) ($5)",
|
||||
"discord-uploadnewver": "нова преработка на",
|
||||
"discord-uploadcomplete": "$1 подигна $2 $3 $4 ($5, $6×$7, $8)",
|
||||
"discord-filedeletecomplete": "$1 избриша верзија на податотека $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 поврати некои верзии на податотека $2 $3",
|
||||
"discord-afterimportpage": "$1 увезе $2 (увезени $4/$3 преработки)",
|
||||
"discord-timestampformat": "**G:i ч. e:**",
|
||||
"discord-articlemergecomplete": "$1 спои преработки од $2 во $3",
|
||||
"discord-approvedrevsrevisionapproved": "$1 одобри нова преработка на $2 (преработка $3) од корисникот $4",
|
||||
"discord-approvedrevsrevisionunapproved": "$1 тргна одобрение од одобрената преработка за $2",
|
||||
"discord-approvedrevsfilerevisionapproved": "$1 одобри нова преработка на податотека на $2 ($3) од корисникот $4",
|
||||
"discord-approvedrevsfilerevisionunapproved": "$1 тргна одобрение од одобрената преработка на податотека за $2",
|
||||
"discord-renameusercomplete": "$1 го преименуваше корисникот $2 во $3"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Railfail536"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Wysyła wiadomości o dokonywanych akcjach na serwer Discord",
|
||||
"discord-userlinks": "$1 ($2|$3)",
|
||||
"discord-revisionlinks": "($1) $2 $3",
|
||||
"discord-talk": "d",
|
||||
"discord-contribs": "w",
|
||||
"discord-diff": "różn.",
|
||||
"discord-minor": "(m)",
|
||||
"discord-size": "($1)",
|
||||
"discord-edit": "$1 edytował $2 $3 $4",
|
||||
"discord-articledelete": "$1 usunął $2 $3 ($4 wersje usunięte)",
|
||||
"discord-undeleterev": "wersje",
|
||||
"discord-articleundelete": "$1 odtworzył $2 $3 $4",
|
||||
"discord-revvisibility": "$1 zmienił widoczność $2 wersji $3",
|
||||
"discord-articleprotect": "$1 zmienił poziom zabezpoeczenia strony $2 $2 $3 ($4)",
|
||||
"discord-titlemove": "$1 przeniósł $2 na $3 $4 $5",
|
||||
"discord-localusercreated": "$1 założył konto",
|
||||
"discord-blocktimeformat": "d F Y H:i",
|
||||
"discord-blockipcomplete": "$1 zablokował $2 $3 ($4)",
|
||||
"discord-unblockusercomplete": "$1 zdjął blokadę z $2",
|
||||
"discord-usergroupschanged": "$1 zmienił uprawnienia użytkownika $2 $3 ($4) ($5)",
|
||||
"discord-uploadnewver": "nową wersję",
|
||||
"discord-uploadcomplete": "$1 przesłał $2 $3 $4 ($5, $6x$7, $8)",
|
||||
"discord-filedeletecomplete": "$1 usunął wersję pliku $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 odtworzył wersje pliku $2 $3"
|
||||
}
|
||||
+38
-23
@@ -1,27 +1,42 @@
|
||||
{
|
||||
"discord-desc": "The description used for the Discord extension",
|
||||
"discord-userlinks": "Used for display of the user links. Parameters\n* $1 - User page link\n* $2 - discord-talk\n* $3 - discord-contribs",
|
||||
"discord-revisionlinks": "Used for display of revision links. Parameters\n* $1 - discord-diff\n* $2 - discord-minor\n* $3 - discord-size",
|
||||
"discord-talk": "Used as the text for $2 in discord-userlinks",
|
||||
"discord-contribs": "Used as the text for $3 in discord-userlinks",
|
||||
"discord-diff": "Used as the text for $1 in discord-revisionlinks",
|
||||
"discord-minor": "Used as the text for $2 in discord-revisionlinks",
|
||||
"discord-size": "Used as the text for $3 in discord-revisionlinks. Parameters\n* $1 - Calculated revision size diff",
|
||||
"discord-edit": "Message sent to Discord for when a page edit is made. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - discord-revisionlinks\n* $4 - Summary (always surrounded in tildes)",
|
||||
"discord-create": "Message sent to Discord for when a page creation is made. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - discord-revisionlinks\n* $4 - Summary (always surrounded in tildes)",
|
||||
"discord-articledelete": "Message sent to Discord when a page is deleted. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - Reason (always surrounded in tildes)\n* $4 - Number of revisions deleted",
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Abijeet Patro",
|
||||
"Jayden",
|
||||
"Jayden Bailey"
|
||||
]
|
||||
},
|
||||
"discord-desc": "The description used for the Discord extension",
|
||||
"discord-userlinks": "Used for display of the user links. Parameters\n* $1 - User page link\n* $2 - discord-talk\n* $3 - discord-contribs",
|
||||
"discord-revisionlinks": "Used for display of revision links. Parameters\n* $1 - discord-diff\n* $2 - discord-minor\n* $3 - discord-size",
|
||||
"discord-talk": "Used as the text for $2 in discord-userlinks",
|
||||
"discord-contribs": "Used as the text for $3 in discord-userlinks",
|
||||
"discord-diff": "Used as the text for $1 in discord-revisionlinks",
|
||||
"discord-minor": "Used as the text for $2 in discord-revisionlinks",
|
||||
"discord-size": "Used as the text for $3 in discord-revisionlinks. Parameters\n* $1 - Calculated revision size diff",
|
||||
"discord-edit": "Message sent to Discord for when a page edit is made. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - discord-revisionlinks\n* $4 - Summary (always surrounded in tildes)",
|
||||
"discord-create": "Message sent to Discord for when a page creation is made. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - discord-revisionlinks\n* $4 - Summary (always surrounded in tildes)",
|
||||
"discord-articledelete": "Message sent to Discord when a page is deleted. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - Reason (always surrounded in tildes)\n* $4 - Number of revisions deleted",
|
||||
"discord-undeleterev": "Used as the text for $2 in discord-articleundelete if revisions are being undeleted rather than a page",
|
||||
"discord-articleundelete": "Message sent to Discord when pages/revisions are undeleted. Parameters:\n* $1 - discord-userlinks\n* $2 - discord-undeleterev\n* $3 - Page link\n* $4 - Comment (always surrounded in tildes)",
|
||||
"discord-revvisibility": "Message sent to Discord when the visibility of revisions is changed. Parameters:\n$1 - discord-userlinks\n* $2 - Number of revisions\n* $3 - Page link",
|
||||
"discord-articleprotect": "Message sent to Discord when an article's protection is changed. Parameters:\n$1 - discord-userlinks\n* $2 - Page link\n* $3 - Reason (always surrounded in tildes)\n* $4 - Protection settings",
|
||||
"discord-titlemove": "Message sent to Discord when an article is moved. Parameters:\n$1 - discord-userlinks\n$2 - Old page link\n$3 - New page link\n$4 - Reason (always surrounded in tildes)\n$5 - discord-revisionlinks",
|
||||
"discord-localusercreated": "Message sent to Discord when a user registers. Parameters:\n$1 - discord-userlinks",
|
||||
"discord-blocktimeformat": "The formatting used in the date() function for displaying the time a user is blocked for.",
|
||||
"discord-blockipcomplete": "Message sent to Discord when a user is blocked. Parameters:\n$1 - discord-userlinks (performer)\n$2 - discord-userlinks (target)\n$3 - Reason (always surrounded in tildes)\n$4 - Expiry text (using discord-blocktimeformat)",
|
||||
"discord-unblockusercomplete": "Message sent to Discord when a user is unblocked. Parameters:\n$1 - discord-userlinks (performer)\n$2 - discord-userlinks (target)",
|
||||
"discord-usergroupschanged": "Message sent to Discord when a user's group is changed. Parameters:\n$1 - discord-userlinks (performer)\n$2 -discord-userlinks (target)\n$3 - Reason (always surrounded in tildes)\n$4 - Added rights (prepended by +)\n$5 - Removed rights (prepended by -)",
|
||||
"discord-articleundelete": "Message sent to Discord when pages/revisions are undeleted.\nParameters:\n* $1 - discord-userlinks\n* $2 - discord-undeleterev\n* $3 - Page link\n* $4 - Comment (always surrounded in tildes)",
|
||||
"discord-revvisibility": "Message sent to Discord when the visibility of revisions is changed.\nParameters:\n* $1 - discord-userlinks\n* $2 - Number of revisions\n* $3 - Page link",
|
||||
"discord-articleprotect": "Message sent to Discord when an article's protection is changed.\nParameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - Reason (always surrounded in tildes)\n* $4 - Protection settings",
|
||||
"discord-titlemove": "Message sent to Discord when an article is moved. Parameters:\n* $1 - discord-userlinks\n* $2 - Old page link\n* $3 - New page link\n* $4 - Reason (always surrounded in tildes)\n* $5 - discord-revisionlinks",
|
||||
"discord-localusercreated": "Message sent to Discord when a user registers.\nParameters:\n* $1 - discord-userlinks",
|
||||
"discord-blocktimeformat": "The formatting used in the date() function for displaying the time a user is blocked for.\n\nSee also: https://www.php.net/manual/en/datetime.format.php",
|
||||
"discord-blockipcomplete": "Message sent to Discord when a user is blocked. Parameters:\n* $1 - discord-userlinks (performer)\n* $2 - discord-userlinks (target)\n* $3 - Reason (always surrounded in tildes)\n* $4 - Expiry text (using discord-blocktimeformat)",
|
||||
"discord-unblockusercomplete": "Message sent to Discord when a user is unblocked. Parameters:\n$1 - discord-userlinks (performer)\n$2 - discord-userlinks (target)",
|
||||
"discord-usergroupschanged": "Message sent to Discord when a user's group is changed. Parameters:\n* $1 - discord-userlinks (performer)\n* $2 - discord-userlinks (target)\n* $3 - Reason (always surrounded in tildes)\n* $4 - Added rights (prepended by +)\n* $5 - Removed rights (prepended by -)",
|
||||
"discord-uploadnewver": "Used as the text for $2 in discord-uploadcomplete",
|
||||
"discord-uploadcomplete": "Message sent to Discord when an upload is made. Parameters:\n$1 - discord-userlinks\n$2 - discord-uploadnewver\n$3 - File link\n$4 - Comment (always surrounded in tildes)\n$5 - Size (formatted as KB/MB/GB)\n$6 - File width\n$7 - File height\n$8 - File MIME type",
|
||||
"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-uploadcomplete": "Message sent to Discord when an upload is made. Parameters:\n\n* $1 - discord-userlinks\n* $2 - discord-uploadnewver\n* $3 - File link\n* $4 - Comment (always surrounded in tildes)\n* $5 - Size (formatted as KB/MB/GB)\n* $6 - File width\n* $7 - File height\n* $8 - File MIME type",
|
||||
"discord-filedeletecomplete": "Message sent to Discord when a file version is deleted (not an entire file).\nParameters:\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).\nParameters:\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 gmdate() function for displaying the time an event happened in UTC.\n\nSee also: https://www.php.net/manual/en/datetime.format.php",
|
||||
"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).\nParameters:\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).\nParameters:\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).\nParameters:\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).\nParameters:\n* $1 - discord-userlinks (admin user)\n* $2 - Target link",
|
||||
"discord-renameusercomplete": "Message sent to Discord when a user is renamed (Renameuser extension).\nParameters:\n* $1 - discord-userlinks (admin user)\n* $2 - Old username\n* $3 - New username link"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Eleassar"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Pošlje sporočila na kanal Discord ob nekaterih dogodkih",
|
||||
"discord-talk": "t",
|
||||
"discord-contribs": "c",
|
||||
"discord-diff": "razl",
|
||||
"discord-minor": "(m)",
|
||||
"discord-edit": "$1 je uredil_a $2 $3 $4",
|
||||
"discord-create": "$1 je ustvaril_a $2 $3 $4",
|
||||
"discord-articledelete": "$1 je izbrisal_a $2 $3 (izbrisanih $4 redakcij)",
|
||||
"discord-undeleterev": "redakcije za",
|
||||
"discord-articleundelete": "$1 je odizbrisal_a $2 $3 $4",
|
||||
"discord-revvisibility": "$1 je spremenil_a vidnost $2 redakcij strani $3",
|
||||
"discord-articleprotect": "$1 je spremenil_a zaščito $2 $3 ($4)",
|
||||
"discord-titlemove": "$1 je prestavil_a $2 na $3 $4 $5",
|
||||
"discord-localusercreated": "Registracija $1",
|
||||
"discord-blocktimeformat": "d. F Y, H:i",
|
||||
"discord-blockipcomplete": "$1 je blokiral_a $2 $3 ($4)",
|
||||
"discord-unblockusercomplete": "$1 je odblokiral_a $2",
|
||||
"discord-usergroupschanged": "$1 je spremenil_a pravice $2 $3 ($4) ($5)",
|
||||
"discord-uploadnewver": "nova različica datoteke",
|
||||
"discord-uploadcomplete": "$1 je naložil_a $2 $3 $4 ($5, $6 × $7, $8)",
|
||||
"discord-filedeletecomplete": "$1 je izbrisal_a različico datoteke $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 je obnovil_a nekaj različic datoteke $2 $3",
|
||||
"discord-afterimportpage": "$1 je uvozil_a $2 (uvoženih $4/$3 redakcij)",
|
||||
"discord-timestampformat": "**H:i e:**",
|
||||
"discord-articlemergecomplete": "$1 je združil_a redakcije iz $2 v $3",
|
||||
"discord-approvedrevsrevisionapproved": "$1 je odobril_a novo redakcijo $2 (redakcija $3) uporabnika_ce $4",
|
||||
"discord-approvedrevsrevisionunapproved": "$1 je od-odobrila odobreno redakcijo za $2",
|
||||
"discord-approvedrevsfilerevisionapproved": "$1 je odobril_a novo različico datoteke $2 ($3) uporabnika_ce $4",
|
||||
"discord-approvedrevsfilerevisionunapproved": "$1 je od-odobrila odobreno redakcijo datoteke za $2",
|
||||
"discord-renameusercomplete": "$1 je preimenoval_a uporabnika $2 v $3"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Milicevic01"
|
||||
]
|
||||
},
|
||||
"discord-talk": "р",
|
||||
"discord-contribs": "д",
|
||||
"discord-diff": "разл",
|
||||
"discord-minor": "(м)",
|
||||
"discord-create": "$1 ја направио $2 $3 $4",
|
||||
"discord-localusercreated": "$1 се регистровао",
|
||||
"discord-blockipcomplete": "$1 је блокирао $2 $3 ($4)",
|
||||
"discord-afterimportpage": "$1 је увезао $2 (увезено $4/$3 ревизија)",
|
||||
"discord-renameusercomplete": "$1 је преименовао корисника $2 у $3"
|
||||
}
|
||||
+324
-67
@@ -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 = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $userIdentity );
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'PageContentSaveComplete', $wikiPage->getTitle()->getNamespace(), $user ) ) {
|
||||
if ( DiscordUtils::isDisabled( $hookName, $wikiPage->getTitle()->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -22,44 +31,47 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a page is deleted
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleDeleteComplete
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/PageDeleteComplete
|
||||
*/
|
||||
public static function onArticleDeleteComplete( &$article, User &$user, $reason, $id, $content, LogEntry $logEntry, $archivedRevisionCount ) {
|
||||
global $wgDiscordNoBots, $wgDiscordNoMinor, $wgDiscordNoNull;
|
||||
public static function onPageDeleteComplete( MediaWiki\Page\ProperPageIdentity $page, MediaWiki\Permissions\Authority $deleter, string $reason, int $pageID, MediaWiki\Revision\RevisionRecord $deletedRev, ManualLogEntry $logEntry, int $archivedRevisionCount ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'ArticleDeleteComplete';
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'ArticleDeleteComplete', $article->getTitle()->getNamespace(), $user ) ) {
|
||||
$user = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity($deleter->getUser());
|
||||
$page = MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle($page);
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, $page->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -69,10 +81,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( $page->getTitle(), $page->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
( $reason ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $reason ) ) . '`' ) : '' ),
|
||||
$archivedRevisionCount)->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -81,17 +93,25 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleUndelete
|
||||
*/
|
||||
public static function onArticleUndelete( Title $title, $create, $comment, $oldPageId, $restoredPages ) {
|
||||
global $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;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-articleundelete', DiscordUtils::createUserLinks( $wgUser ),
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot change
|
||||
return true;
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
@@ -100,16 +120,24 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleRevisionVisibilitySet
|
||||
*/
|
||||
public static function onArticleRevisionVisibilitySet( &$title, $ids, $visibilityChangeMap ) {
|
||||
global $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;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-revvisibility', DiscordUtils::createUserLinks( $wgUser ),
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot change
|
||||
return true;
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
@@ -119,8 +147,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;
|
||||
}
|
||||
|
||||
@@ -130,21 +159,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 = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $userIdentity );
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'TitleMoveComplete', $title->getNamespace(), $user ) ) {
|
||||
if ( DiscordUtils::isDisabled( $hookName, $old->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -154,11 +185,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;
|
||||
}
|
||||
|
||||
@@ -167,12 +198,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;
|
||||
}
|
||||
|
||||
@@ -181,7 +214,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;
|
||||
}
|
||||
|
||||
@@ -192,10 +227,15 @@ class DiscordHooks {
|
||||
$expiryMsg = $expiry;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-blockipcomplete', DiscordUtils::createUserLinks( $user ), DiscordUtils::createUserLinks( $block->getTarget() ),
|
||||
( $block->mReason ? ('`' . DiscordUtils::truncateText( $block->mReason ) . '`' ) : '' ),
|
||||
$target = $block->getTargetUserIdentity();
|
||||
if ( $target === null ) {
|
||||
$target = $block->getTargetName();
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-blockipcomplete', DiscordUtils::createUserLinks( $user ), DiscordUtils::createUserLinks( $target ),
|
||||
( $block->getReasonComment()->text ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $block->getReasonComment()->text ) ) . '`' ) : '' ),
|
||||
$expiryMsg )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -204,12 +244,19 @@ 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);
|
||||
$target = $block->getTargetUserIdentity();
|
||||
if ( $target === null ) {
|
||||
$target = $block->getTargetName();
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-unblockusercomplete', DiscordUtils::createUserLinks( $user ), DiscordUtils::createUserLinks( $target ) )->text();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -218,7 +265,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;
|
||||
}
|
||||
|
||||
@@ -229,10 +278,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;
|
||||
}
|
||||
|
||||
@@ -241,10 +290,18 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/UploadComplete
|
||||
*/
|
||||
public static function onUploadComplete( &$image ) {
|
||||
$lf = $image->getLocalFile();
|
||||
$user = $lf->getUser( $type = 'object' ); // only supported in MW 1.31+
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'UploadComplete';
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'UploadComplete', NS_FILE, $user ) ) {
|
||||
$lf = $image->getLocalFile();
|
||||
$user = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $lf->getUploader() );
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, NS_FILE, $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot change
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -253,13 +310,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;
|
||||
}
|
||||
|
||||
@@ -268,7 +325,15 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/FileDeleteComplete
|
||||
*/
|
||||
public static function onFileDeleteComplete( $file, $oldimage, $article, $user, $reason ) {
|
||||
if ( DiscordUtils::isDisabled( 'FileDeleteComplete', NS_FILE, $user ) ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'FileDeleteComplete';
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, NS_FILE, $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot change
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -278,9 +343,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;
|
||||
}
|
||||
|
||||
@@ -289,14 +354,206 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/FileUndeleteComplete
|
||||
*/
|
||||
public static function onFileUndeleteComplete( $title, $fileVersions, $user, $reason ) {
|
||||
if ( DiscordUtils::isDisabled( 'FileUndeleteComplete', NS_FILE, $user ) ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'FileUndeleteComplete';
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, NS_FILE, $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot change
|
||||
return true;
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a page is imported
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/AfterImportPage
|
||||
*/
|
||||
public static function onAfterImportPage( $title, $origTitle, $revCount, $sRevCount, $pageInfo ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'AfterImportPage';
|
||||
|
||||
$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-afterimportpage', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
$revCount, $sRevCount)->plain();
|
||||
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 = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $displayedFile->getUploader() );
|
||||
|
||||
$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 = MediaWikiServices::getInstance()->getUserFactory()->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;
|
||||
}
|
||||
}
|
||||
|
||||
+136
-57
@@ -1,5 +1,8 @@
|
||||
<?php
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
|
||||
class DiscordUtils {
|
||||
/**
|
||||
* Checks if criteria is met for this action to be cancelled
|
||||
@@ -28,6 +31,10 @@ class DiscordUtils {
|
||||
}
|
||||
if ( is_array( $wgDiscordDisabledUsers ) ) {
|
||||
if ( !is_null( $user ) ) {
|
||||
if ( $user instanceof UserIdentity ) {
|
||||
$user = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity($user);
|
||||
}
|
||||
|
||||
if ( $user instanceof User ) {
|
||||
if ( in_array( $user->getName(), $wgDiscordDisabledUsers ) ) {
|
||||
// User shouldn't trigger a message, return true
|
||||
@@ -45,8 +52,8 @@ class DiscordUtils {
|
||||
/**
|
||||
* Handles sending a webhook to Discord using cURL
|
||||
*/
|
||||
public static function handleDiscord ($msg) {
|
||||
global $wgDiscordWebhookURL;
|
||||
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
|
||||
@@ -67,41 +74,81 @@ class DiscordUtils {
|
||||
// Strip whitespace to just one space
|
||||
$stripped = preg_replace('/\s+/', ' ', $msg);
|
||||
|
||||
DeferredUpdates::addCallableUpdate( function() use ( $stripped, $urls ) {
|
||||
$json_data = [ 'content' => "$stripped" ];
|
||||
$json = json_encode($json_data);
|
||||
if ( $wgDiscordPrependTimestamp ) {
|
||||
// Add timestamp
|
||||
$dateString = gmdate( wfMessage( 'discord-timestampformat' )->text() );
|
||||
$stripped = $dateString . ' ' . $stripped;
|
||||
}
|
||||
|
||||
// Set up cURL multi handlers
|
||||
$c_handlers = [];
|
||||
$result = [];
|
||||
$mh = curl_multi_init();
|
||||
if ( $wgDiscordUseEmojis ) {
|
||||
// Add emoji
|
||||
$emoji = $wgDiscordEmojis[$hookName];
|
||||
$stripped = $emoji . ' ' . $stripped;
|
||||
}
|
||||
|
||||
foreach ($urls as &$value) {
|
||||
$c_handlers[$value] = curl_init( $value );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_POST, 1 ); // Send as a POST request
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_POSTFIELDS, $json ); // Send the JSON in the POST request
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_FOLLOWLOCATION, 1 );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_HEADER, 0 );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_RETURNTRANSFER, 1 );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_CONNECTTIMEOUT, 10 ); // Add a timeout for connecting to the site
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_TIMEOUT, 20 ); // Do not allow cURL to run for a long time
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_USERAGENT, 'mw-discord/1.0 (github.com/jaydenkieran)' ); // Add a unique user agent
|
||||
curl_multi_add_handle( $mh, $c_handlers[$value] );
|
||||
$response = curl_exec( $ch );
|
||||
DeferredUpdates::addCallableUpdate( function() use ( $stripped, $urls, $wgDiscordUseFileGetContents ) {
|
||||
$user_agent = 'mw-discord/1.0 (github.com/jaydenkieran)';
|
||||
$json_data = [
|
||||
'content' => "$stripped",
|
||||
'allowed_mentions' => [
|
||||
'parse' => []
|
||||
]
|
||||
];
|
||||
$json = json_encode($json_data);
|
||||
|
||||
if ( $wgDiscordUseFileGetContents ) {
|
||||
// They want to use file_get_contents
|
||||
foreach ($urls as &$value) {
|
||||
$contextOpts = [
|
||||
'http' => [
|
||||
'header' => 'Content-Type: application/x-www-form-urlencoded',
|
||||
'method' => 'POST', // Send as a POST request
|
||||
'user_agent' => $user_agent, // Add a unique user agent
|
||||
'content' => $json, // Send the JSON in the POST request
|
||||
'ignore_errors' => true // If the call fails, let's not do anything with it
|
||||
]
|
||||
];
|
||||
|
||||
$context = stream_context_create( $contextOpts );
|
||||
$result = file_get_contents( $value, false, $context );
|
||||
}
|
||||
} else {
|
||||
// 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
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_POSTFIELDS, $json ); // Send the JSON in the POST request
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_FOLLOWLOCATION, 1 );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_HEADER, 0 );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_RETURNTRANSFER, 1 );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_CONNECTTIMEOUT, 10 ); // Add a timeout for connecting to the site
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_TIMEOUT, 10 ); // Do not allow cURL to run for a long time
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_USERAGENT, $user_agent ); // Add a unique user agent
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_HTTPHEADER, array(
|
||||
'Content-Type: application/json'
|
||||
));
|
||||
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);
|
||||
}
|
||||
|
||||
$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);
|
||||
curl_multi_remove_handle($mh, $ch);
|
||||
}
|
||||
|
||||
curl_multi_close($mh);
|
||||
} );
|
||||
|
||||
return true;
|
||||
@@ -119,11 +166,34 @@ class DiscordUtils {
|
||||
/**
|
||||
* Creates links for a specific MediaWiki User object
|
||||
*/
|
||||
public static function createUserLinks ($user) {
|
||||
$userPage = DiscordUtils::createMarkdownLink( $user, $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(), Title::newFromText("Special:Contributions/" . $user)->getFullURL( '', '', $proto = PROTO_HTTP ) );
|
||||
$text = wfMessage( 'discord-userlinks', $userPage, $userTalk, $userContribs )->text();
|
||||
public static function createUserLinks ( $user ) {
|
||||
global $wgDiscordMaxCharsUsernames;
|
||||
|
||||
if ( $user instanceof UserIdentity ) {
|
||||
// If we were passed a UserIdentity object, get the relevant user.
|
||||
$user = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity($user);
|
||||
}
|
||||
|
||||
if ( $user instanceof User ) {
|
||||
$isAnon = $user->isAnon();
|
||||
$contribs = Title::newFromText("Special:Contributions/" . $user);
|
||||
$user_abbr = strval($user);
|
||||
|
||||
if ($wgDiscordMaxCharsUsernames) {
|
||||
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 we were given a string, handle this differently.
|
||||
$text = wfMessage( 'discord-userlinks', $user, 'n/a', 'n/a' )->text();
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
@@ -131,26 +201,26 @@ 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 == '' ) {
|
||||
$size .= wfMessage( 'discord-size', sprintf( "%d", $revision->getSize() ) )->text();
|
||||
}
|
||||
$text = wfMessage( 'discord-revisionlinks', $diff, $minor, $size )->text();
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Strip bad characters from a URL
|
||||
*/
|
||||
@@ -160,20 +230,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];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,6 +259,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