Compare commits

..

1 Commits

Author SHA1 Message Date
Jayden 1af68db747 Update README.md 2023-05-19 01:26:21 +01:00
37 changed files with 992 additions and 2348 deletions
+35 -41
View File
@@ -1,68 +1,68 @@
# Matrix (mw-matrix)
MediaWiki extension for sending notifications to a Matrix 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 Matrix server using a webhook.
> ⚠️ **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.
Multiple webhook URLs are supported and messages will be sent to all of them.
**Live demo**: https://runescape.wiki (https://matrix.gg/runescapewiki)
**Live demo**: https://runescape.wiki (https://discord.gg/runescapewiki)
<p align="center">
<img src="https://i.imgur.com/tCehglJ.png" alt="Example"/>
</p>
## Requirements
- **Matrix webhook URL**: Found by editing a channel -> Integrations -> Webhooks
- **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 current version.
- We do not support versions of MediaWiki that are considered end-of-life.
- The `master` branch may contain changes that are only applicable to the current alpha version of MediaWiki.
- **[cURL](https://www.php.net/curl)** (likely installed already). Without this, the extension may still work, but requests will be sent inefficiently.
- **Discord webhook URL**: This can be obtained by editing a channel on a server with the correct permissions.
- **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-matrix.git -b REL1_35 Matrix`
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
// Load the extension
wfLoadExtension( 'Matrix' );
wfLoadExtension( 'Discord' );
// Set the webhook URL(s) (string or array)
$wgMatrixWebhookURL = [ '' ];
$wgDiscordWebhookURL = [ '' ];
```
For further configuration variables, see [below](#configuration).
### Getting a webhook URL
To get a webhook URL for use with this extension, open the Matrix client and go to a server where you have the `Manage Webhooks` permission. Click the cog icon when hovering over a text channel, switch to the Webhooks tab on the left of the interface, and click 'Create webhook'. The webhook URL can then be copied from that interface.
To get a webhook URL for use with this extension, open the Discord client and go to a server where you have the `Manage Webhooks` permission. Click the cog icon when hovering over a text channel, switch to the Webhooks tab on the left of the interface, and click 'Create webhook'. The webhook URL can then be copied from that interface.
## Configuration
This extension can be configured using the `LocalSettings.php` file in your MediaWiki installation.
| Variable | Type | Description |
| --- | --- | --- |
| `$wgMatrixWebhookURL` | string/array | Matrix webhook URLs
| `$wgDiscordWebhookURL` | string/array | Discord webhook URLs
### Optional
These parameters aren't required for the extension to work.
| Variable | Type | Description | Default |
| --- | --- | --- | --- |
| `$wgMatrixNoBots` | bool | Do not send notifications that are triggered by a [bot account](https://www.mediawiki.org/wiki/Manual:Bots) | `true`
| `$wgMatrixNoMinor` | bool | Do not send notifications that are for [minor edits](https://www.mediawiki.org/wiki/Help:Minor_edit) | `false`
| `$wgMatrixNoNull` | bool | Do not send notifications for [null edits](https://www.mediawiki.org/wiki/Manual:Purge#Null_edits) | `true`
| `$wgMatrixSuppressPreviews` | bool | Force previews for links in Matrix messages to be suppressed | `true`
| `$wgMatrixMaxChars` | int | Maximum amount of characters for user-generated text (e.g summaries, reasons). Set to `null` to disable truncation | `null`
| `$wgMatrixMaxCharsUsernames` | int | Maximum amount of characters for usernames. Set to `null` to disable truncation | `25`
| `$wgMatrixDisabledHooks` | string array | List of hooks to disable sending webhooks for (see [below](#hooks-used)) | `[]`
| `$wgMatrixDisabledNS` | int array | List of namespace **IDs** to disable sending webhooks for. (see [below](#namespaces)) | `[]`
| `$wgMatrixDisabledUsers` | string array | List of users whose performed actions shouldn't send webhooks | `[]`
| `$wgMatrixPrependTimestamp` | bool | Prepend a timestamp (in UTC) to all sent messages. The format can be changed by editing the MediaWiki message `matrix-timestampformat` | `false`
| `$wgMatrixUseEmojis` | bool | Prepend emojis to different types of messages to help distinguish them | `false`
| `$wgMatrixEmojis` | string associative array | Map of hook names and their associated emojis to prepend to messages if `$wgMatrixUseEmojis` is enabled | See [extension.json](/extension.json#L30)
| `$wgDiscordNoBots` | bool | Do not send notifications that are triggered by a [bot account](https://www.mediawiki.org/wiki/Manual:Bots) | `true`
| `$wgDiscordNoMinor` | bool | Do not send notifications that are for [minor edits](https://meta.wikimedia.org/wiki/Help:Minor_edit) | `false`
| `$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
- `PageSaveComplete` - New edits to pages and page creations
- `PageDeleteComplete` - Page deletions
- `PageUndeleteComplete` - Page restorations
- `ArticleDeleteComplete` - Page deletions
- `ArticleUndelete` - Page restorations
- `ArticleRevisionVisibilitySet` - Revision visibility changes
- `ArticleProtectComplete` - Page protections
- `PageMoveComplete` - Page moves
@@ -74,8 +74,7 @@ These parameters aren't required for the extension to work.
- `FileDeleteComplete` - File revision was deleted
- `FileUndeleteComplete` - File revision was restored
- `AfterImportPage` - Page was imported
- `ArticleMergeComplete` - Article histories were merged
- `RenameUserComplete` - Rename was completed
- `ArticleMergeComplete` - Article histories was merged
### [Approved Revs](https://www.mediawiki.org/wiki/Extension:Approved_Revs)
- `ApprovedRevsRevisionApproved` - Revision was approved
@@ -83,15 +82,10 @@ These parameters aren't required for the extension to work.
- `ApprovedRevsFileRevisionApproved` - File revision was approved
- `ApprovedRevsFileRevisionUnapproved` - File revision was unapproved
## Namespaces
As we use namespace IDs the following resources might be helpful:
- [Built in namespaces' IDs](https://www.mediawiki.org/wiki/Manual:Namespace#Built-in_namespaces)
- [Extension default namespaces](https://www.mediawiki.org/wiki/Extension_default_namespaces)
## Translation
You can submit translations for this extension on [Translatewiki.net](https://translatewiki.net/wiki/Special:Translate/mwgithub-mw-matrix).
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).
## License
This extension is available under the MIT license. You can [see here](LICENSE) for more information.
This extension was inspired by Szmyk's [mediawiki-matrix](https://github.com/Szmyk/mediawiki-matrix) project.
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.
+50 -65
View File
@@ -1,41 +1,37 @@
{
"name": "Matrix",
"name": "Discord",
"author": [
"[https://github.com/jayktaylor Jayden Bailey]",
"[https://git.pvv.ntnu.no/Projects Programvareverkstedet]"
"[https://github.com/jaydenkieran Jayden Bailey]"
],
"url": "https://git.pvv.ntnu.no/Projects/mediawiki-matrix-notifs",
"version": "1.2",
"descriptionmsg": "matrix-desc",
"url": "https://github.com/jaydenkieran/mw-discord",
"version": "1.0.12",
"descriptionmsg": "discord-desc",
"license-name": "MIT",
"requires": {
"MediaWiki": ">= 1.40.0"
"MediaWiki": ">= 1.36.0"
},
"manifest_version": 1,
"config": {
"MatrixHomeserverURL": "",
"MatrixUser": "",
"MatrixPassword": "",
"MatrixRooms": [],
"MatrixNoBots": true,
"MatrixNoMinor": false,
"MatrixNoNull": true,
"MatrixMaxChars": null,
"MatrixMaxCharsUsernames": 25,
"MatrixDisabledHooks": [],
"MatrixDisabledNS": [],
"MatrixDisabledUsers": [
"Redirect fixer"
],
"MatrixPrependTimestamp": false,
"MatrixUseEmojis": false,
"MatrixEmojis": {
"PageSaveComplete": ":pencil2:",
"PageDeleteComplete": ":wastebasket:",
"PageUndeleteComplete": ":wastebasket:",
"DiscordWebhookURL": [],
"DiscordNoBots": true,
"DiscordNoMinor": false,
"DiscordNoNull": true,
"DiscordSuppressPreviews": true,
"DiscordMaxChars": null,
"DiscordMaxCharsUsernames": 25,
"DiscordDisabledHooks": [],
"DiscordDisabledNS": [],
"DiscordDisabledUsers": [],
"DiscordPrependTimestamp": false,
"DiscordUseFileGetContents": false,
"DiscordUseEmojis": false,
"DiscordEmojis": {
"PageContentSaveComplete": ":pencil2:",
"ArticleDeleteComplete": ":wastebasket:",
"ArticleUndelete": ":wastebasket:",
"ArticleRevisionVisibilitySet": ":spy:",
"ArticleProtectComplete": ":lock:",
"PageMoveComplete": ":truck:",
"TitleMoveComplete": ":truck:",
"LocalUserCreated": ":wave:",
"BlockIpComplete": ":no_entry_sign:",
"UnblockUserComplete": ":no_entry_sign:",
@@ -48,47 +44,36 @@
"ApprovedRevsRevisionApproved": ":white_check_mark:",
"ApprovedRevsRevisionUnapproved": ":white_check_mark:",
"ApprovedRevsFileRevisionApproved": ":white_check_mark:",
"ApprovedRevsFileRevisionUnapproved": ":white_check_mark:",
"RenameUserComplete": ":people_holding_hands:"
"ApprovedRevsFileRevisionUnapproved": ":white_check_mark:"
}
},
"AutoloadNamespaces": {
"MediaWiki\\Extension\\Matrix\\": "src/"
"AutoloadClasses": {
"DiscordHooks": "src/DiscordHooks.php",
"DiscordUtils": "src/Utils.php"
},
"MessagesDirs": {
"mw-matrix": "i18n"
},
"HookHandlers": {
"main": {
"class": "MediaWiki\\Extension\\Matrix\\MatrixHooks",
"services": [
"Matrix.MatrixMessageSender"
]
}
"mw-discord": "i18n"
},
"Hooks": {
"PageSaveComplete": "main",
"PageDeleteComplete": "main",
"PageUndeleteComplete": "main",
"ArticleRevisionVisibilitySet": "main",
"ArticleProtectComplete": "main",
"PageMoveComplete": "main",
"LocalUserCreated": "main",
"BlockIpComplete": "main",
"UnblockUserComplete": "main",
"UserGroupsChanged": "main",
"UploadComplete": "main",
"FileDeleteComplete": "main",
"FileUndeleteComplete": "main",
"AfterImportPage": "main",
"ArticleMergeComplete": "main",
"ApprovedRevsRevisionApproved": "main",
"ApprovedRevsRevisionUnapproved": "main",
"ApprovedRevsFileRevisionApproved": "main",
"ApprovedRevsFileRevisionUnapproved": "main",
"RenameUserComplete": "main"
},
"ServiceWiringFiles": [
"src/ServiceWiring.php"
]
"PageSaveComplete": "DiscordHooks::onPageSaveComplete",
"ArticleDeleteComplete": "DiscordHooks::onArticleDeleteComplete",
"ArticleUndelete": "DiscordHooks::onArticleUndelete",
"ArticleRevisionVisibilitySet": "DiscordHooks::onArticleRevisionVisibilitySet",
"ArticleProtectComplete": "DiscordHooks::onArticleProtectComplete",
"PageMoveComplete": "DiscordHooks::onPageMoveComplete",
"LocalUserCreated": "DiscordHooks::onLocalUserCreated",
"BlockIpComplete": "DiscordHooks::onBlockIpComplete",
"UnblockUserComplete": "DiscordHooks::onUnblockUserComplete",
"UserGroupsChanged": "DiscordHooks::onUserGroupsChanged",
"UploadComplete": "DiscordHooks::onUploadComplete",
"FileDeleteComplete": "DiscordHooks::onFileDeleteComplete",
"FileUndeleteComplete": "DiscordHooks::onFileUndeleteComplete",
"AfterImportPage": "DiscordHooks::onAfterImportPage",
"ArticleMergeComplete": "DiscordHooks::onArticleMergeComplete",
"ApprovedRevsRevisionApproved": "DiscordHooks::onApprovedRevsRevisionApproved",
"ApprovedRevsRevisionUnapproved": "DiscordHooks::onApprovedRevsRevisionUnapproved",
"ApprovedRevsFileRevisionApproved": "DiscordHooks::onApprovedRevsFileRevisionApproved",
"ApprovedRevsFileRevisionUnapproved": "DiscordHooks::onApprovedRevsFileRevisionUnapproved",
"RenameUserComplete": "DiscordHooks::onRenameUserComplete"
}
}
-39
View File
@@ -1,39 +0,0 @@
{
"@metadata": {
"authors": [
"Asma",
"Meno25",
"Mohammed Qays"
]
},
"matrix-desc": "يرسل رسائل إلى قناة Matrix عند وقوع أحداث معينة",
"matrix-talk": "ت",
"matrix-contribs": "ج",
"matrix-diff": "فرق",
"matrix-minor": "(م)",
"matrix-msg-page-edited": "قام $1 بإنشاء $2 $3 $4",
"matrix-msg-page-created": "قام $1 بإنشاء $2 $3 $4",
"matrix-msg-page-deleted": "تم حذف $1 $2 $3 (تم حذف $4 من المراجعات)",
"matrix-msg-page-undeleted-revs": "المراجعات لـ",
"matrix-msg-page-undeleted": "$1 قام بإلغاء حذف $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 غيرت رؤية $2 من المراجعات على $3",
"matrix-msg-page-protect": "$1 تم تغييره لحماية $2 $3 ( $4 )",
"matrix-msg-page-moved": "قام $1 بنقل من $2 إلى $3 $4 $5",
"matrix-msg-user-registered": "تم تسجيل $1",
"matrix-msg-user-block-timeformat": "d F Y H:i",
"matrix-msg-user-block": "$1 منع $2 $3 ($4)",
"matrix-msg-user-block-partial": "$1 محجوب جزئياً $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 قام بإلغاء منع $2",
"matrix-msg-user-groups-changed": "$1 غير حقوق $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "إصدار جديد من",
"matrix-msg-file-upload": "قام $1 بتحميل $2 $3 $4 ($5، $6×$7 ،$8)",
"matrix-msg-file-delete": "قام $1 بحذف نسخة من الملف $2 $3",
"matrix-msg-file-undelete": "استعاد $1 بعض إصدارات الملف $2 $3",
"matrix-msg-import": "قام $1 باستيراد $2 (تم استيراد مراجعات $4 / $3)",
"matrix-msg-page-merge": "دمج $1 المراجعات من $2 إلى $3",
"matrix-msg-ext-approvedrevs-approved": "وافق $1 على مراجعة جديدة بقيمة $2 (المراجعة $3) من المستخدم $4",
"matrix-msg-ext-approvedrevs-unapproved": "لم يوافق $1 على مراجعة الملف المعتمدة لـ $2",
"matrix-msg-ext-approvedrevs-approved-file": "وافق $1 على مراجعة ملف جديد بقيمة $2 ($3) من المستخدم $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "لم يوافق $1 على مراجعة الملف المعتمدة لـ $2",
"matrix-msg-user-rename": "أعاد $1 تسمية المستخدم $2 إلى $3"
}
-15
View File
@@ -1,15 +0,0 @@
{
"@metadata": {
"authors": [
"আফতাবুজ্জামান"
]
},
"matrix-talk": "আ",
"matrix-contribs": "অ",
"matrix-diff": "পার্থক্য",
"matrix-minor": "(অ)",
"matrix-msg-page-edited": "$1 $2 সম্পাদনা করেছেন $3 $4",
"matrix-msg-page-created": "$1 $2 তৈরি করেছেন $3 $4",
"matrix-msg-user-registered": "$1 নিবন্ধিত হয়েছে",
"matrix-msg-user-block": "$1 $2-কে বাধা দিয়েছেন $3 ($4)"
}
-35
View File
@@ -1,35 +0,0 @@
{
"@metadata": {
"authors": [
"Умар"
]
},
"matrix-desc": "Цхьацца хиламаш хилча, Matrix канале хаамаш дӀакхачабо.",
"matrix-talk": "д",
"matrix-contribs": "c",
"matrix-diff": "башха",
"matrix-minor": "(m)",
"matrix-msg-page-edited": "$1 хийцам бина $2 $3 $4",
"matrix-msg-page-created": "$1 кхоьллина $2 $3 $4",
"matrix-msg-page-deleted": "$1 дӀайаьккхина $2 $3 ($4 версеш дӀайаьхна)",
"matrix-msg-page-undeleted-revs": "версеш",
"matrix-msg-page-undeleted": "$1 меттахӀоттийна $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 хийцина $2 версин гуш хилар $3 тӀе",
"matrix-msg-page-protect": "$1 хийцина ларйар $2 $3 ($4)",
"matrix-msg-page-moved": "$1 дехьайаьккхина $2 тӀе $3 $4 $5.",
"matrix-msg-user-registered": "$1 регистраци йина",
"matrix-msg-user-block": "$1 блоктоьхна $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 блокдӀайаьккхина $2",
"matrix-msg-user-groups-changed": "$1 бакъонаш хийцина $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "керла верси",
"matrix-msg-file-upload": "$1 чуйаьккхина $2 $3 $4 ($5, $6x$7, $8)",
"matrix-msg-file-delete": "$1 дӀайаьккхина файлан верси $2 $3",
"matrix-msg-file-undelete": "$1 меттахӀоттийна цхьайолу версеш файлан $2 $3",
"matrix-msg-import": "$1 импорт йина $2 (импорт йина $4/$3 версеш)",
"matrix-msg-page-merge": "$1 цхьаьнатоьхна версеш $2 - $3",
"matrix-msg-ext-approvedrevs-approved": "$1 тӀечӀагӀйина керла верси $2 (верси $3) декъашхочун $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 тӀечӀагӀйина верси $2 тӀе ца эцна",
"matrix-msg-ext-approvedrevs-approved-file": "$1 тӀечӀагӀйина $2 ($3) файлан керла верси декъашхочуьнгара $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 тӀе ца эцна $2 файлан тӀечӀагӀйина верси",
"matrix-msg-user-rename": "$1 декъашхочун хийцина $2 → $3"
}
-17
View File
@@ -1,17 +0,0 @@
{
"@metadata": {
"authors": [
"Ceirios"
]
},
"matrix-desc": "Anfon negeseuon i sianel Matrix pan fydd digwyddiadau penodol yn digwydd",
"matrix-talk": "s",
"matrix-contribs": "c",
"matrix-diff": "gwahan",
"matrix-minor": "(b)",
"matrix-msg-page-edited": "Golygodd $1 $2 $3 $4",
"matrix-msg-page-created": "Crëodd $1 $2 $3 $4",
"matrix-msg-page-deleted": "Dilëodd $1 $2 $3 (dilëwyd $4 o olygiadau)",
"matrix-msg-page-undeleted-revs": "golygiadau ar gyfer",
"matrix-msg-page-undeleted": "Adferodd $1 $2 $3 $4"
}
-39
View File
@@ -1,39 +0,0 @@
{
"@metadata": {
"authors": [
"Brettchenweber",
"Fyoouki",
"PretzelRocky",
"TomatoCake"
]
},
"matrix-desc": "Sendet Nachrichten an einen Matrix-Kanal, wenn bestimmte Ereignisse eintreten",
"matrix-talk": "Diskussion",
"matrix-contribs": "Beiträge",
"matrix-diff": "Unterschied",
"matrix-minor": "(K)",
"matrix-msg-page-edited": "$1 bearbeitete $2 $3 $4",
"matrix-msg-page-created": "$1 erstellte $2 $3 $4",
"matrix-msg-page-deleted": "$1 löschte $2 $3 ($4 revisionen gelöscht)",
"matrix-msg-page-undeleted-revs": "revisionen für",
"matrix-msg-page-undeleted": "$1 hat $2 wiederhergestellt $3 $4",
"matrix-msg-rev-visibility-changed": "$1 veränderte die Sichtbarkeit von $2 revisionen auf $3",
"matrix-msg-page-protect": "$1 änderte den Schutz von $2 $3 ($4)",
"matrix-msg-page-moved": "$1 verschob $2 zu $3 $4 $5",
"matrix-msg-user-registered": "$1 hat sich registriert",
"matrix-msg-user-block": "$1 blockierte $2 $3 ($4)",
"matrix-msg-user-block-partial": "$1 hat $2 teilweise gesperrt $3 ($4)",
"matrix-msg-user-unblock": "$1 entsperrte $2",
"matrix-msg-user-groups-changed": "$1 hat die Benutzerrechte geändert von $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "neue Version von",
"matrix-msg-file-upload": "$1 lud $2 $3 $4 ($5, $6x$7, $8)",
"matrix-msg-file-delete": "$1 hat eine Version der Datei gelöscht $2 $3",
"matrix-msg-file-undelete": "$1 hat eine Version einer Datei wiederhergestellt von $2 $3",
"matrix-msg-import": "$1 importierte $2 (Import $4/$3 revisionen)",
"matrix-msg-page-merge": "$1 hat die Revisionen von $2 mit $3 zusammengeführt",
"matrix-msg-ext-approvedrevs-approved": "$1 genehmigte eine neue Revision von $2 (Revision $3) von $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 hat die genehmigte Revsision von $2 zurückgezogen.",
"matrix-msg-ext-approvedrevs-approved-file": "$1 genehmigte eine neue Dateirevision von $2 ($3) durch Benutzer $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 hat die genehmigte Dateirevision von $2 zurückgezogen",
"matrix-msg-user-rename": "$1 hat Benutzer von $2 in $3 umbenannt"
}
-35
View File
@@ -1,35 +0,0 @@
{
"@metadata": {
"authors": [
"Dogogos123",
"Norhorn",
"Spyridon Eftychios Kokotos"
]
},
"matrix-desc": "Στέλνει μηνύματα σε ένα κανάλι Matrix όταν συμβαίνουν ορισμένα συμβάντα",
"matrix-diff": "διαφορά",
"matrix-minor": "(μ)",
"matrix-msg-page-edited": "$1 επεξεργάστηκε $2 $3 $4.",
"matrix-msg-page-created": "$1 δημιούργησε $2 $3 $4",
"matrix-msg-page-deleted": "$1 διαγράφηκε $2 $3 ($4 αναθεωρήσεις διαγράφηκαν)",
"matrix-msg-page-undeleted-revs": "αναθεωρήσεις για",
"matrix-msg-page-undeleted": "$1 επανέφερε $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 άλλαξε την ορατότητα των $2 αναθεωρήσεων στο $3",
"matrix-msg-page-protect": "$1 άλλαξε προστασία του $2 $3 ($4)",
"matrix-msg-page-moved": "$1 μετακίνησε $2 στα $3 $4 $5",
"matrix-msg-user-registered": "$1 εγγεγραμμένος",
"matrix-msg-user-block": "$1 αποκλεισμένο $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 ξεμπλόκαρε $2",
"matrix-msg-user-groups-changed": "$1 άλλαξε τα δικαιώματα των $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "νέα έκδοση του",
"matrix-msg-file-upload": "$1 μεταφορτώθηκε $2 $3 $4 ( $5 , $6 x $7 , $8 )",
"matrix-msg-file-delete": "$1 διέγραψε μια έκδοση του αρχείου $2 $3",
"matrix-msg-file-undelete": "$1 επανέφερε ορισμένες εκδόσεις του αρχείου $2 $3",
"matrix-msg-import": "$1 εισήχθη $2 (εισαγμένες $4 / $3 αναθεωρήσεις)",
"matrix-msg-page-merge": "$1 συγχώνευσε αναθεωρήσεις από $2 σε $3",
"matrix-msg-ext-approvedrevs-approved": "$1 ενέκρινε μια νέα αναθεώρηση των $2 (αναθεώρηση $3 ) από τον χρήστη $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 κατάργησε την έγκριση της εγκεκριμένης αναθεώρησης του αρχείου για $2",
"matrix-msg-ext-approvedrevs-approved-file": "$1 ενέκρινε μια νέα αναθεώρηση αρχείου $2 ( $3 ) από τον χρήστη $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 κατάργησε την έγκριση της εγκεκριμένης αναθεώρησης του αρχείου για $2",
"matrix-msg-user-rename": "$1 μετονόμασε τον χρήστη $2 σε $3"
}
+33 -34
View File
@@ -4,38 +4,37 @@
"Jayden Bailey"
]
},
"matrix-desc": "Sends messages to a Matrix channel when certain events occur",
"matrix-userlinks": "$1 ($2|$3)",
"matrix-revisionlinks": "($1) $2 $3",
"matrix-talk": "t",
"matrix-contribs": "c",
"matrix-diff": "diff",
"matrix-minor": "(m)",
"matrix-size": "($1)",
"matrix-msg-page-edited": "$1 edited $2 $3 $4",
"matrix-msg-page-created": "$1 created $2 $3 $4",
"matrix-msg-page-deleted": "$1 deleted $2 $3 ($4 revisions deleted)",
"matrix-msg-page-undeleted-revs": "revisions for",
"matrix-msg-page-undeleted": "$1 undeleted $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 changed visibility of $2 revisions on $3",
"matrix-msg-page-protect": "$1 changed protection of $2 $3 ($4)",
"matrix-msg-page-moved": "$1 moved $2 to $3 $4 $5",
"matrix-msg-user-registered": "$1 registered",
"matrix-msg-user-block-timeformat": "d F Y H:i",
"matrix-msg-user-block": "$1 blocked $2 $3 ($4)",
"matrix-msg-user-block-partial": "$1 partially blocked $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 unblocked $2",
"matrix-msg-user-groups-changed": "$1 changed rights of $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "new version of",
"matrix-msg-file-upload": "$1 uploaded $2 $3 $4 ($5, $6x$7, $8)",
"matrix-msg-file-delete": "$1 deleted a version of file $2 $3",
"matrix-msg-file-undelete": "$1 restored some versions of file $2 $3",
"matrix-msg-import": "$1 imported $2 (imported $4/$3 revisions)",
"matrix-timestampformat": "**H:i e:**",
"matrix-msg-page-merge": "$1 merged revisions from $2 into $3",
"matrix-msg-ext-approvedrevs-approved": "$1 approved a new revision of $2 (revision $3) from user $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 unapproved the approved revision for $2",
"matrix-msg-ext-approvedrevs-approved-file": "$1 approved a new file revision of $2 ($3) from user $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 unapproved the approved file revision for $2",
"matrix-msg-user-rename": "$1 renamed the user $2 to $3"
"discord-desc": "Sends messages to a Discord channel when certain events occur",
"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 edited $2 $3 $4",
"discord-create": "$1 created $2 $3 $4",
"discord-articledelete": "$1 deleted $2 $3 ($4 revisions deleted)",
"discord-undeleterev": "revisions for",
"discord-articleundelete": "$1 undeleted $2 $3 $4",
"discord-revvisibility": "$1 changed visibility of $2 revisions on $3",
"discord-articleprotect": "$1 changed protection of $2 $3 ($4)",
"discord-titlemove": "$1 moved $2 to $3 $4 $5",
"discord-localusercreated": "$1 registered",
"discord-blocktimeformat": "d F Y H:i",
"discord-blockipcomplete": "$1 blocked $2 $3 ($4)",
"discord-unblockusercomplete": "$1 unblocked $2",
"discord-usergroupschanged": "$1 changed rights of $2 $3 ($4) ($5)",
"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-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"
}
-35
View File
@@ -1,35 +0,0 @@
{
"@metadata": {
"authors": [
"MatyGamingHD"
]
},
"matrix-desc": "Envía mensajes a un canal de Matrix cuando ocurren ciertos eventos",
"matrix-talk": "d",
"matrix-contribs": "c",
"matrix-diff": "difs",
"matrix-minor": "(m)",
"matrix-msg-page-edited": "$1 editó $2 $3 $4",
"matrix-msg-page-created": "$1 creó $2 $3 $4",
"matrix-msg-page-deleted": "$1 eliminó $2 $3 ($4 revisiones eliminadas)",
"matrix-msg-page-undeleted-revs": "revisiones de",
"matrix-msg-page-undeleted": "$1 restauró $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 cambió la visibilidad de $2 revisiones en $3",
"matrix-msg-page-protect": "$1 cambió la protección de $2 $3 ($4)",
"matrix-msg-page-moved": "$1 movió $2 a $3 $4 $5",
"matrix-msg-user-registered": "$1 se ha registrado",
"matrix-msg-user-block": "$1 bloqueó a $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 desbloqueó a $2",
"matrix-msg-user-groups-changed": "$1 cambió los derechos de $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "nueva versión de",
"matrix-msg-file-upload": "$1 subió $2 $3 $4 ($5, $6x$7, $8)",
"matrix-msg-file-delete": "$1 eliminó una versión del archivo $2 $3",
"matrix-msg-file-undelete": "$1 restauró algunas versiones del archivo $2 $3",
"matrix-msg-import": "$1 importó $2 (importado $4/$3 revisiones)",
"matrix-msg-page-merge": "$1 fusionó las revisiones de $2 en $3",
"matrix-msg-ext-approvedrevs-approved": "$1 aprobó una nueva revisión de $2 (revisión $3) del usuario $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 desaprobó la revisión aprobada de $2",
"matrix-msg-ext-approvedrevs-approved-file": "$1 aprobó una nueva revisión del archivo $2 ($3) del usuario $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 desaprobó la revisión aprobada del archivo $2",
"matrix-msg-user-rename": "$1 renombró al usuario $2 a $3"
}
-36
View File
@@ -1,36 +0,0 @@
{
"@metadata": {
"authors": [
"Gomoko",
"Verdy p"
]
},
"matrix-desc": "Envoie des messages à un canal Matrix quand certains événements surviennent",
"matrix-talk": "t",
"matrix-contribs": "c",
"matrix-diff": "diff",
"matrix-minor": "(m)",
"matrix-msg-page-edited": "$1 a modifié $2 $3: $4",
"matrix-msg-page-created": "$1 a créé $2 $3: $4",
"matrix-msg-page-deleted": "$1 a supprimé $2 ($4 version(s) supprimée(s)): $3",
"matrix-msg-page-undeleted-revs": "versions pour",
"matrix-msg-page-undeleted": "$1 a restauré $2 $3: $4",
"matrix-msg-rev-visibility-changed": "$1 a modifié la visibilité de $2 version(s) sur $3",
"matrix-msg-page-protect": "$1 a modifié la protection de $2 ($4): $3",
"matrix-msg-page-moved": "$1 a renommé $2 en $3 $5: $4",
"matrix-msg-user-registered": "$1 sest inscrit(e)",
"matrix-msg-user-block": "$1 a bloqué $2 ($4): $3",
"matrix-msg-user-unblock": "$1 a débloqué $2",
"matrix-msg-user-groups-changed": "$1 a modifié les droits de $2 ($4) ($5): $3",
"matrix-msg-file-upload-new": "nouvelle version de",
"matrix-msg-file-upload": "$1 a téléversé $2 $3 ($5, $6x$7, $8): $4",
"matrix-msg-file-delete": "$1 a supprimé une version du fichier $2: $3",
"matrix-msg-file-undelete": "$1 a restauré certaines versions du fichier $2: $3",
"matrix-msg-import": "$1 a importé $2 ($4/$3 révisions importées)",
"matrix-msg-page-merge": "$1 a fusionné des versions de $2 vers $3",
"matrix-msg-ext-approvedrevs-approved": "$1 a approuvé une nouvelle version de $2 (version $3) créée par $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 a désapprouvé la version approuvée de $2",
"matrix-msg-ext-approvedrevs-approved-file": "$1 a approuvé une nouvelle version de fichier dans $2 ($3) créée par $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 a désapprouvé la version de fichier approuvée dans $2",
"matrix-msg-user-rename": "$1 a renommé lutilisateur ou lutilisatrice $2 en $3"
}
-37
View File
@@ -1,37 +0,0 @@
{
"@metadata": {
"authors": [
"Toliño"
]
},
"matrix-desc": "Envía mensaxes a unha canle de Matrix cando ocorren certos eventos",
"matrix-talk": "conv",
"matrix-contribs": "contr",
"matrix-diff": "dif",
"matrix-minor": "(m)",
"matrix-msg-page-edited": "$1 editou «$2» $3 $4",
"matrix-msg-page-created": "$1 creou «$2» $3 $4",
"matrix-msg-page-deleted": "$1 eliminou «$2» $3 ($4 revisións eliminadas)",
"matrix-msg-page-undeleted-revs": "revisións de",
"matrix-msg-page-undeleted": "$1 restaurou $2 «$3» $4",
"matrix-msg-rev-visibility-changed": "$1 cambiou a visibilidade de $2 revisións en «$3»",
"matrix-msg-page-protect": "$1 cambiou a protección de «$2» $3 ($4)",
"matrix-msg-page-moved": "$1 trasladou «$2» a «$3» $4 $5",
"matrix-msg-user-registered": "$1 rexistrouse",
"matrix-msg-user-block-timeformat": "d \\d\\e F \\d\\e Y H:i",
"matrix-msg-user-block": "$1 bloqueou a $2 $3 ($4)",
"matrix-msg-user-block-partial": "$1 bloqueou parcialmente a $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 desbloqueou a $2",
"matrix-msg-user-groups-changed": "$1 cambiou os dereitos de $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "unha nova versión de",
"matrix-msg-file-upload": "$1 subiu $2 «$3» $4 ($5, $6×$7, $8)",
"matrix-msg-file-delete": "$1 eliminou unha versión do ficheiro «$2» $3",
"matrix-msg-file-undelete": "$1 restaurou algunhas versións do ficheiro «$2» $3",
"matrix-msg-import": "$1 importou «$2» (importáronse $4/$3 revisións)",
"matrix-msg-page-merge": "$1 fusionou revisións de «$2» en «$3»",
"matrix-msg-ext-approvedrevs-approved": "$1 aprobou unha nova revisión de «$2» (revisión $3) do usuario $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 non aprobou a revisión aprobada de «$2»",
"matrix-msg-ext-approvedrevs-approved-file": "$1 aprobou unha nova revisión do ficheiro «$2» ($3) do usuario $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 non aprobou a revisión aprobada do ficheiro de «$2»",
"matrix-msg-user-rename": "$1 renomeou o usuario $2 a $3"
}
-37
View File
@@ -1,37 +0,0 @@
{
"@metadata": {
"authors": [
"Amire80",
"Neriah"
]
},
"matrix-desc": "שליחת הודעות לערוץ דיסקורד כאשר אירועים מסוימים מתרחשים",
"matrix-talk": "ש",
"matrix-contribs": "ת",
"matrix-diff": "השוואה",
"matrix-minor": "(מ)",
"matrix-msg-page-edited": "חשבון $1 ערך את הדף $2 $3 $4",
"matrix-msg-page-created": "חשבון $1 יצר את הדף $2 $3 $4",
"matrix-msg-page-deleted": "חשבון $1 מחק את הדף $2 $3 (מספר הגרסאות שנמחקו הוא $4)",
"matrix-msg-page-undeleted-revs": "גרסאות של",
"matrix-msg-page-undeleted": "חשבון $1 שחזר ממחיקה את הדף $2 $3 $4",
"matrix-msg-rev-visibility-changed": "חשבון $1 שינה הנראות של $2 גרסאות של הדף $3",
"matrix-msg-page-protect": "חשבון $1 שינה את ההגנה של הדף $2 סיבה: $3 הגדרות הגנה: ($4)",
"matrix-msg-page-moved": "חשבון $1 העביר את הדף $2 לשם $3 $4 $5",
"matrix-msg-user-registered": "חשבון $1 נרשם",
"matrix-msg-user-block": "חשבון $1 חסם אם $2 $3 ($4)",
"matrix-msg-user-block-partial": "$1 נחסם חלקית $2 $3 ($4)",
"matrix-msg-user-unblock": "חשבון $1 שחרר מחסימה את $2",
"matrix-msg-user-groups-changed": "חשבון $1 שינה את ההרשאות של $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "גרסה חדשה של",
"matrix-msg-file-upload": "חשבון $1 העלה את $2 $3 $4 (גודל: $5, מידות: $6x$7, סוג: $8)",
"matrix-msg-file-delete": "חשבון $1 מחק גרסה של הקובץ $2 $3",
"matrix-msg-file-undelete": "חשבון $1 שחזר כמה גרסאות של קובץ $2 $3",
"matrix-msg-import": "חשבון $1 ייבא את $2 (יובאו $4 מתוך $3 גרסאות)",
"matrix-msg-page-merge": "חשבון $1 מיזג גרסאות מתוך $2 לתוך $3",
"matrix-msg-ext-approvedrevs-approved": "חשבון $1 אישר גרסה חדשה של $2 (גרסה $3) של חשבון $4",
"matrix-msg-ext-approvedrevs-unapproved": "חשבון $1 ביטל את אישור של הגרסה המאושרת של $2",
"matrix-msg-ext-approvedrevs-approved-file": "חשבון $1 אישר גרסה חדשה של הקובץ $2 (גיבוב $3) של חשבון $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "חשבון $1 ביטל את אישור של גרסת הקובץ של $2",
"matrix-msg-user-rename": "חשבון $1 שינה את השם של משתמש $2 לשם $3"
}
-37
View File
@@ -1,37 +0,0 @@
{
"@metadata": {
"authors": [
"McDutchie"
]
},
"matrix-desc": "Invia messages a un canal Matrix quando certe eventos occurre",
"matrix-talk": "d",
"matrix-contribs": "c",
"matrix-diff": "diff",
"matrix-minor": "(m)",
"matrix-msg-page-edited": "$1 ha modificate $2 $3 $4",
"matrix-msg-page-created": "$1 ha create $2 $3 $4",
"matrix-msg-page-deleted": "$1 ha delite $2 $3 ($4 versiones delite)",
"matrix-msg-page-undeleted-revs": "versiones pro",
"matrix-msg-page-undeleted": "$1 ha restaurate $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 ha cambiate le visibilitate de $2 versiones sur $3",
"matrix-msg-page-protect": "$1 ha cambiate le protection de $2 $3 ($4)",
"matrix-msg-page-moved": "$1 ha renominate $2 a $3 $4 $5",
"matrix-msg-user-registered": "$1 se ha inscribite",
"matrix-msg-user-block-timeformat": "j F Y H:i",
"matrix-msg-user-block": "$1 ha blocate $2 $3 ($4)",
"matrix-msg-user-block-partial": "$1 ha partialmente blocate $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 ha disblocate $2",
"matrix-msg-user-groups-changed": "$1 ha cambiate le derectos de $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "nove version de",
"matrix-msg-file-upload": "$1 ha incargate un $2 $3 $4 ($5, $6x$7, $8)",
"matrix-msg-file-delete": "$1 ha delite un version del file $2 $3",
"matrix-msg-file-undelete": "$1 ha restaurate alcun versiones del file $2 $3",
"matrix-msg-import": "$1 ha importate $2 ($4/$3 versiones importate)",
"matrix-msg-page-merge": "$1 ha fusionate le versiones de $2 in $3",
"matrix-msg-ext-approvedrevs-approved": "$1 ha approbate un nove version de $2 (version $3) del usator $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 ha disapprobate le version approbate de $2",
"matrix-msg-ext-approvedrevs-approved-file": "$1 ha approbate un nove version del file $2 ($3) del usator $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 ha disapprobate le version approbate del file $2",
"matrix-msg-user-rename": "$1 ha renominate le usator $2 a $3"
}
-38
View File
@@ -1,38 +0,0 @@
{
"@metadata": {
"authors": [
"Tensama0415"
]
},
"matrix-desc": "특정 이벤트가 발생했을 때 Matrix 채널에 메시지를 전송합니다",
"matrix-talk": "토",
"matrix-contribs": "기",
"matrix-diff": "차이",
"matrix-minor": "(잔)",
"matrix-msg-page-edited": "$1님이 $2 문서를 편집함 $3 $4",
"matrix-msg-page-created": "$1님이 $2 문서를 생성함 $3 $4",
"matrix-msg-page-deleted": "$1님이 $2 문서를 삭제함 $3 ($4개 판 삭제됨)",
"matrix-msg-page-undeleted-revs": "(의 판)",
"matrix-msg-page-undeleted": "$1님이 $2 문서를 복구함 $3 $4",
"matrix-msg-rev-visibility-changed": "$1님이 $3 문서의 $2개 판의 공개 여부를 변경함",
"matrix-msg-page-protect": "$1님이 $2 문서의 보호를 변경함 $3 ($4)",
"matrix-msg-page-moved": "$1님이 $2 문서를 $3 문서로 이동함 $4 $5",
"matrix-msg-user-registered": "$1님이 등록함",
"matrix-msg-user-block-timeformat": "Y F d H:i",
"matrix-msg-user-block": "$1님이 $2님을 차단함 $3 ($4)",
"matrix-msg-user-block-partial": "$1님이 $2님을 부분적으로 차단함 $3 ($4)",
"matrix-msg-user-unblock": "$1님이 $2님을 차단 해제함",
"matrix-msg-user-groups-changed": "$1님이 $2님의 권한을 변경함 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "새로운 버전의",
"matrix-msg-file-upload": "$1님이 $2 $3 파일을 업로드함 $4 ($5, $6x$7, $8)",
"matrix-msg-file-delete": "$1님이 $2 파일의 몇몇 버전을 삭제함 $3",
"matrix-msg-file-undelete": "$1님이 $2 파일의 몇몇 버전을 복원함 $3",
"matrix-msg-import": "$1님이 $2 문서를 가져옴 ($4/$3개 판 가져옴)",
"matrix-timestampformat": "**H:i e:**",
"matrix-msg-page-merge": "$1님이 $2판을 $3판으로 병합함",
"matrix-msg-ext-approvedrevs-approved": "$1님이 사용자 $4님이 제출한 $2 문서의 새 판(판 $3)을 승인함",
"matrix-msg-ext-approvedrevs-unapproved": "$1님이 $2 문서의 판을 승인 취소함",
"matrix-msg-ext-approvedrevs-approved-file": "$1님이 사용자 $4님이 제출한 $2 파일의 새 버전($3)을 승인함",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1님이 $2 파일의 판을 승인 취소함",
"matrix-msg-user-rename": "$1님이 사용자 $2님의 이름을 $3님으로 변경함"
}
-28
View File
@@ -1,28 +0,0 @@
{
"@metadata": {
"authors": [
"Elefentiste"
]
},
"matrix-talk": "d",
"matrix-contribs": "c",
"matrix-diff": "dif",
"matrix-minor": "(m)",
"matrix-msg-page-edited": "$1 ia edita $2 $3 $4",
"matrix-msg-page-created": "$1 ia crea $2 $3 $4",
"matrix-msg-page-deleted": "$1 ia sutrae $2 $3 ($4 revisas ia es sutraeda)",
"matrix-msg-page-undeleted": "$1 ia desutrae $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 ia cambia vidablia de $2 revisas en $3",
"matrix-msg-page-protect": "$1 ia cambia proteje de $2 $3 ($4)",
"matrix-msg-page-moved": "$1 ia move $2 a $3 $4 $5",
"matrix-msg-user-block": "$1 ia impedi $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 ia desimpedi $2",
"matrix-msg-file-upload": "$1 ia carga $2 $3 $4 ($5, $6x$7, $8)",
"matrix-msg-import": "$1 ia emporta $2 (emportada $4/$3 revisas)",
"matrix-msg-page-merge": "$1 ia fusa revisas de $2 a en $3",
"matrix-msg-ext-approvedrevs-approved": "$1 ia aproba un revisa nova de $2 (revisa $3) de usor $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 ia desaproba la revisa aprobada per $2",
"matrix-msg-ext-approvedrevs-approved-file": "$1 ia aproba un revisa de fix nova de $2 ($3) de usor $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 ia desaproba la revisa de fix aprobada per $2",
"matrix-msg-user-rename": "$1 ia renomi la usor $2 a $3"
}
-38
View File
@@ -1,38 +0,0 @@
{
"@metadata": {
"authors": [
"Bjankuloski06"
]
},
"matrix-desc": "Испраќа пораки на канал на Дискорд кога ќе се случат извесни настани",
"matrix-talk": "р",
"matrix-contribs": "п",
"matrix-diff": "разл",
"matrix-minor": "(м)",
"matrix-msg-page-edited": "$1 уреди $2 $3 $4",
"matrix-msg-page-created": "$1 создаде $2 $3 $4",
"matrix-msg-page-deleted": "$1 избриша $2 $3 (избришани $4 преработки)",
"matrix-msg-page-undeleted-revs": "преработки за",
"matrix-msg-page-undeleted": "$1 поврати $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 смени видливост на $2 преработки на $3",
"matrix-msg-page-protect": "$1 смени заштита на $2 $3 ($4)",
"matrix-msg-page-moved": "$1 премести $2 на $3 $4 $5",
"matrix-msg-user-registered": "$1 зачленети",
"matrix-msg-user-block-timeformat": "j F Y G:i ч.",
"matrix-msg-user-block": "$1 блокираше $2 $3 ($4)",
"matrix-msg-user-block-partial": "$1 делумно го блокираше $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 одблокираше $2",
"matrix-msg-user-groups-changed": "$1 ги смени правата на $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "нова преработка на",
"matrix-msg-file-upload": "$1 подигна $2 $3 $4 ($5, $6×$7, $8)",
"matrix-msg-file-delete": "$1 избриша верзија на податотека $2 $3",
"matrix-msg-file-undelete": "$1 поврати некои верзии на податотека $2 $3",
"matrix-msg-import": "$1 увезе $2 (увезени $4/$3 преработки)",
"matrix-timestampformat": "**G:i ч. e:**",
"matrix-msg-page-merge": "$1 спои преработки од $2 во $3",
"matrix-msg-ext-approvedrevs-approved": "$1 одобри нова преработка на $2 (преработка $3) од корисникот $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 тргна одобрение од одобрената преработка за $2",
"matrix-msg-ext-approvedrevs-approved-file": "$1 одобри нова преработка на податотека на $2 ($3) од корисникот $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 тргна одобрение од одобрената преработка на податотека за $2",
"matrix-msg-user-rename": "$1 го преименуваше корисникот $2 во $3"
}
-38
View File
@@ -1,38 +0,0 @@
{
"@metadata": {
"authors": [
"EdoAug",
"Jon Harald Søby"
]
},
"matrix-desc": "Sender meldinger til en Matrix-kanal når visse hendelser forekommer",
"matrix-talk": "d",
"matrix-contribs": "b",
"matrix-diff": "diff",
"matrix-minor": "(m)",
"matrix-msg-page-edited": "$1 redigerte $2 $3 $4",
"matrix-msg-page-created": "$1 opprettet $2 $3 $4",
"matrix-msg-page-deleted": "$1 slettet $2 $3 ($4 sideversjoner slettet)",
"matrix-msg-page-undeleted-revs": "sideversjoner for",
"matrix-msg-page-undeleted": "$1 gjenopprettet $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 endret synligheten til $2 sideversjoner for $3",
"matrix-msg-page-protect": "$1 endra beskyttelsen av $2 $3 ($4)",
"matrix-msg-page-moved": "$1 flyttet $2 til $3 $4 $5",
"matrix-msg-user-registered": "$1 registrerte",
"matrix-msg-user-block-timeformat": "j. F Y \"kl.\" H:i",
"matrix-msg-user-block": "$1 blokkerte $2 $3 ($4)",
"matrix-msg-user-block-partial": "$1 blokkerte $2 delvis $3 ($4)",
"matrix-msg-user-unblock": "$1 opphevde blokkeringen til $2",
"matrix-msg-user-groups-changed": "$1 endret rettighetene til $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "ny versjon av",
"matrix-msg-file-upload": "$1 lastet opp $2 $3 $4 ($5, $6x$7, $8)",
"matrix-msg-file-delete": "$1 slettet en versjon av fila $2 $3",
"matrix-msg-file-undelete": "$1 gjenopprettet noen versjoner av fila $2 $3",
"matrix-msg-import": "$1 importerte $2 (importerte $4/$3 sideversjoner)",
"matrix-msg-page-merge": "$1 flettet sideversjoner fra $2 inn i $3",
"matrix-msg-ext-approvedrevs-approved": "$1 godkjente en ny sideversjon av $2 (sideversjon $3) fra brukeren $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 trakk tilbake godkjenningen av sideversjonen for $2",
"matrix-msg-ext-approvedrevs-approved-file": "$1 godkjente en ny versjon av fila $2 ($3) fra brukeren $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 trakk tilbake godkjenningen av filversjon for $2",
"matrix-msg-user-rename": "$1 omdøpte brukeren $2 til $3"
}
-40
View File
@@ -1,40 +0,0 @@
{
"@metadata": {
"authors": [
"Elphie",
"McDutchie",
"SPQRobin",
"Vistaus"
]
},
"matrix-desc": "Stuurt berichten naar een Matrix-kanaal wanneer bepaalde gebeurtenissen plaatsvinden",
"matrix-talk": "o",
"matrix-contribs": "b",
"matrix-diff": "wijz",
"matrix-minor": "(k)",
"matrix-msg-page-edited": "$1 heeft $2 bewerkt $3 $4",
"matrix-msg-page-created": "$1 heeft $2 aangemaakt $3 $4",
"matrix-msg-page-deleted": "$1 heeft $2 verwijderd $3 ($4 versies verwijderd)",
"matrix-msg-page-undeleted-revs": "versies voor",
"matrix-msg-page-undeleted": "$1 heeft $2 teruggezet $3 $4",
"matrix-msg-rev-visibility-changed": "$1 heeft de zichtbaarheid van $2 versies op $3 veranderd",
"matrix-msg-page-protect": "$1 heeft de beveiliging van $2 veranderd $3 ($4)",
"matrix-msg-page-moved": "$1 heeft $2 hernoemd naar $3 $4 $5",
"matrix-msg-user-registered": "$1 heeft zich ingeschreven",
"matrix-msg-user-block-timeformat": "j F Y H:i",
"matrix-msg-user-block": "$1 heeft $2 geblokkeerd $3 ($4)",
"matrix-msg-user-block-partial": "$1 heeft $2 gedeeltelijk geblokkeerd $3 ($4)",
"matrix-msg-user-unblock": "$1 heeft $2 gedeblokkeerd",
"matrix-msg-user-groups-changed": "$1 heeft de rechten van $2 veranderd $3 ($4) ($5)",
"matrix-msg-file-upload-new": "nieuwe versie van",
"matrix-msg-file-upload": "$1 heeft een $2 $3 geüpload $4 ($5, $6x$7, $8)",
"matrix-msg-file-delete": "$1 heeft een versie van het bestand $2 verwijderd $3",
"matrix-msg-file-undelete": "$1 heeft bepaalde versies van het bestand $2 teruggezet $3",
"matrix-msg-import": "$1 heeft $2 geïmporteerd (er zijn $4 van de $3 versies geïmporteerd)",
"matrix-msg-page-merge": "$1 heeft de versies van $2 samengevoegd met $3",
"matrix-msg-ext-approvedrevs-approved": "$1 heeft een nieuwe versie van $2 goedgekeurd (versie $3, auteur $4)",
"matrix-msg-ext-approvedrevs-unapproved": "$1 heeft de goedkeuring van de goedgekeurde versie van $2 ingetrokken",
"matrix-msg-ext-approvedrevs-approved-file": "$1 heeft een nieuwe bestandsversie van $2 ($3) goedgekeurd, auteur: $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 heeft de goedkeuring van de goedgekeurde bestandsversie van $2 ingetrokken",
"matrix-msg-user-rename": "$1 heeft de gebruiker $2 hernoemd naar $3"
}
+24 -19
View File
@@ -4,23 +4,28 @@
"Railfail536"
]
},
"matrix-desc": "Wysyła wiadomości o dokonywanych akcjach na serwer Matrix",
"matrix-talk": "d",
"matrix-contribs": "w",
"matrix-diff": "różn.",
"matrix-msg-page-edited": "$1 edytował $2 $3 $4",
"matrix-msg-page-deleted": "$1 usunął $2 $3 ($4 wersje usunięte)",
"matrix-msg-page-undeleted-revs": "wersje",
"matrix-msg-page-undeleted": "$1 odtworzył $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 zmienił widoczność $2 wersji $3",
"matrix-msg-page-protect": "$1 zmienił poziom zabezpoeczenia strony $2 $2 $3 ($4)",
"matrix-msg-page-moved": "$1 przeniósł $2 na $3 $4 $5",
"matrix-msg-user-registered": "$1 założył konto",
"matrix-msg-user-block": "$1 zablokował $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 zdjął blokadę z $2",
"matrix-msg-user-groups-changed": "$1 zmienił uprawnienia użytkownika $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "nową wersję",
"matrix-msg-file-upload": "$1 przesłał $2 $3 $4 ($5, $6x$7, $8)",
"matrix-msg-file-delete": "$1 usunął wersję pliku $2 $3",
"matrix-msg-file-undelete": "$1 odtworzył wersje pliku $2 $3"
"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"
}
+34 -39
View File
@@ -1,45 +1,40 @@
{
"@metadata": {
"authors": [
"Abijeet Patro",
"Amire80",
"Jayden",
"Jayden Bailey",
"McDutchie"
"Jayden Bailey"
]
},
"matrix-desc": "The description used for the Matrix extension",
"matrix-userlinks": "{{optional}}\nUsed for display of the user links. Parameters\n* $1 - User page link\n* $2 - {{msg-mw|matrix-talk}}\n* $3 - {{msg-mw|matrix-contribs}}",
"matrix-revisionlinks": "{{Optional}}\nUsed for display of revision links. Parameters\n* $1 - {{msg-mw|matrix-diff}}\n* $2 - {{msg-mw|matrix-minor}}\n* $3 - {{msg-mw|matrix-size}}",
"matrix-talk": "Short for \"talk\".\n\nUsed as the text for $2 in {{msg-mw|matrix-userlinks}}",
"matrix-contribs": "Short for \"contributions\".\n\nUsed as the text for $3 in {{msg-mw|matrix-userlinks}}",
"matrix-diff": "Used as the text for $1 in matrix-revisionlinks",
"matrix-minor": "Short for \"minor edit\". The letter should be the same as in {{msg-mw|Minoreditletter}}.\n\nUsed as the text for $2 in {{msg-mw|matrix-revisionlinks}}.",
"matrix-size": "{{Optional}}\nUsed as the text for $3 in matrix-revisionlinks. Parameters\n* $1 - Calculated revision size diff",
"matrix-msg-page-edited": "Message sent to Matrix for when a page edit is made. Parameters:\n* $1 - {{msg-mw|matrix-userlinks}}\n* $2 - Page link\n* $3 - {{msg-mw|matrix-revisionlinks}}\n* $4 - Summary (always surrounded in tildes)",
"matrix-msg-page-created": "Message sent to Matrix for when a page creation is made. Parameters:\n* $1 - {{msg-mw|matrix-userlinks}}\n* $2 - Page link\n* $3 - {{msg-mw|matrix-revisionlinks}}\n* $4 - Summary (always surrounded in tildes)",
"matrix-msg-page-deleted": "Message sent to Matrix when a page is deleted. Parameters:\n* $1 - {{msg-mw|matrix-userlinks}}\n* $2 - Page link\n* $3 - Reason (always surrounded in tildes)\n* $4 - Number of revisions deleted",
"matrix-msg-page-undeleted-revs": "Used as the text for $2 in matrix-articleundelete if revisions are being undeleted rather than a page",
"matrix-msg-page-undeleted": "Message sent to Matrix when pages/revisions are undeleted.\nParameters:\n* $1 - {{msg-mw|matrix-userlinks}}\n* $2 - {{msg-mw|matrix-msg-undeleted-revs}}\n* $3 - Page link\n* $4 - Comment (always surrounded in tildes)",
"matrix-msg-rev-visibility-changed": "Message sent to Matrix when the visibility of revisions is changed.\nParameters:\n* $1 - {{msg-mw|matrix-userlinks}}\n* $2 - Number of revisions\n* $3 - Page link",
"matrix-msg-page-protect": "Message sent to Matrix when an article's protection is changed.\nParameters:\n* $1 - {{msg-mw|matrix-userlinks}}\n* $2 - Page link\n* $3 - Reason (always surrounded in tildes)\n* $4 - Protection settings",
"matrix-msg-page-moved": "Message sent to Matrix when an article is moved. Parameters:\n* $1 - {{msg-mw|matrix-userlinks}}\n* $2 - Old page link\n* $3 - New page link\n* $4 - Reason (always surrounded in tildes)\n* $5 - {{msg-mw|matrix-revisionlinks}}",
"matrix-msg-user-registered": "Message sent to Matrix when a user registers.\nParameters:\n* $1 - {{msg-mw|matrix-userlinks}}",
"matrix-msg-user-block-timeformat": "{{optional}}\n\nThe 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",
"matrix-msg-user-block": "Message sent to Matrix when a user is blocked. Parameters:\n* $1 - {{msg-mw|matrix-userlinks}} (performer)\n* $2 - {{msg-mw|matrix-userlinks}} (target)\n* $3 - Reason (always surrounded in tildes)\n* $4 - Expiry text (using {{msg-mw|matrix-msg-user-block-timeformat}})",
"matrix-msg-user-block-partial": "Message sent to Matrix when a user is blocked partially. Parameters:\n* $1 - {{msg-mw|matrix-userlinks}} (performer)\n* $2 - {{msg-mw|matrix-userlinks}} (target)\n* $3 - Reason (always surrounded in tildes)\n* $4 - Expiry text (using {{msg-mw|matrix-msg-user-block-timeformat}})",
"matrix-msg-user-unblock": "Message sent to Matrix when a user is unblocked. Parameters:\n* $1 - {{msg-mw|matrix-userlinks}} (performer)\n* $2 - {{msg-mw|matrix-userlinks}} (target)",
"matrix-msg-user-groups-changed": "Message sent to Matrix when a user's group is changed. Parameters:\n* $1 - {{msg-mw|matrix-userlinks}} (performer)\n* $2 - {{msg-mw|matrix-userlinks}} (target)\n* $3 - Reason (always surrounded in tildes)\n* $4 - Added rights (prepended by +)\n* $5 - Removed rights (prepended by -)",
"matrix-msg-file-upload-new": "Used as the text for $2 in {{msg-mw|matrix-msg-file-upload}}",
"matrix-msg-file-upload": "Message sent to Matrix when an upload is made. Parameters:\n\n* $1 - {{msg-mw|matrix-userlinks}}\n* $2 - {{msg-mw|matrix-msg-file-upload-new}}\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",
"matrix-msg-file-delete": "Message sent to Matrix when a file version is deleted (not an entire file).\nParameters:\n* $1 - {{msg-mw|matrix-userlinks}}\n* $2 - File link\n* $3 - Comment (always surrounded in tildes)",
"matrix-msg-file-undelete": "Message sent to Matrix when a file version is restored (not an entire file).\nParameters:\n* $1 - {{msg-mw|matrix-userlinks}}\n* $2 - File link\n* $3 - Comment (always surrounded in tildes)",
"matrix-msg-import": "Message sent to Matrix when a page is imported. Parameters:\n* $1 - {{msg-mw|matrix-userlinks}}\n* $2 - Page link\n* $3 - Number of revisions in XML file\n* $4 - Number of revisions successfully imported",
"matrix-timestampformat": "{{optional}}\n\nThe 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",
"matrix-msg-page-merge": "Message sent to Matrix when page histories are merged. Parameters:\n* $1 - {{msg-mw|matrix-userlinks}}\n* $2 - Target link\n* $3 - Destination link",
"matrix-msg-ext-approvedrevs-approved": "Message sent to Matrix when a revision is approved (Approved Revs extension).\nParameters:\n* $1 - {{msg-mw|matrix-userlinks}} (admin user)\n* $2 - Target link\n* $3 - Revision link or ID\n* $4 - {{msg-mw|matrix-userlinks}} (revision author) or ID",
"matrix-msg-ext-approvedrevs-unapproved": "Message sent to Matrix when a revision is unapproved (Approved Revs extension).\nParameters:\n* $1 - {{msg-mw|matrix-userlinks}} (admin user)\n* $2 - Target link",
"matrix-msg-ext-approvedrevs-approved-file": "Message sent to Matrix when a file revision is approved (Approved Revs extension).\nParameters:\n* $1 - {{msg-mw|matrix-userlinks}} (admin user)\n* $2 - Target link\n* $3 - SHA of uploaded file\n* $4 - {{msg-mw|matrix-userlinks}} (revision author)",
"matrix-msg-ext-approvedrevs-unapproved-file": "Message sent to Matrix when a file revision is unapproved (Approved Revs extension).\nParameters:\n* $1 - {{msg-mw|matrix-userlinks}} (admin user)\n* $2 - Target link",
"matrix-msg-user-rename": "Message sent to Matrix when a user is renamed.\nParameters:\n* $1 - {{msg-mw|matrix-userlinks}} (admin user)\n* $2 - Old username\n* $3 - New username link"
"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-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-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-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"
}
-42
View File
@@ -1,42 +0,0 @@
{
"@metadata": {
"authors": [
"Engineer56",
"Kareyac",
"Yurina Tatiana"
]
},
"matrix-desc": "Отправляет сообщения на канал в Matrix при возникновении некоторых событий.",
"matrix-userlinks": "$1 ($2|$3)",
"matrix-revisionlinks": "($1) $2 $3",
"matrix-talk": "о",
"matrix-contribs": "c",
"matrix-diff": "разн.",
"matrix-minor": "(m)",
"matrix-size": "($1)",
"matrix-msg-page-edited": "$1 отредактировал $2 $3 $4",
"matrix-msg-page-created": "$1 создал $2 $3 $4",
"matrix-msg-page-deleted": "$1 удалил $2 $3 ($4 версии удалены)",
"matrix-msg-page-undeleted-revs": "версии",
"matrix-msg-page-undeleted": "$1 восстановил $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 изменил видимость $2 версий на $3",
"matrix-msg-page-protect": "$1 изменил защиту $2 $3 ($4)",
"matrix-msg-page-moved": "$1 переместил $2 на $3 $4 $5",
"matrix-msg-user-registered": "$1 зарегистрировался",
"matrix-msg-user-block-timeformat": "d F Y H:i",
"matrix-msg-user-block": "$1 заблокировал $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 разблокировал $2",
"matrix-msg-user-groups-changed": "$1 изменил права $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "новая версия",
"matrix-msg-file-upload": "$1 загрузил $2 $3 $4 ($5, $6x$7, $8)",
"matrix-msg-file-delete": "$1 удалил версию файла $2 $3",
"matrix-msg-file-undelete": "$1 восстановил некоторые версии файла $2 $3",
"matrix-msg-import": "$1 импортировал $2 (импортировано $4/$3 версий)",
"matrix-timestampformat": "**H:i e:**",
"matrix-msg-page-merge": "$1 объединил версии из $2 в $3",
"matrix-msg-ext-approvedrevs-approved": "$1 одобрил новую версию $2 (версия $3) от пользователя $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 не одобрил утверждённую версию $2",
"matrix-msg-ext-approvedrevs-approved-file": "$1 одобрил новую версию файла $2 ($3) от пользователя $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 не одобрил утверждённую версию файла $2",
"matrix-msg-user-rename": "$1 переименовал пользователя $2 в $3"
}
-37
View File
@@ -1,37 +0,0 @@
{
"@metadata": {
"authors": [
"Eleassar",
"Upwinxp"
]
},
"matrix-desc": "Pošlje sporočila na kanal Matrix ob nekaterih dogodkih",
"matrix-talk": "t",
"matrix-contribs": "c",
"matrix-diff": "razl",
"matrix-minor": "(m)",
"matrix-msg-page-edited": "$1 je uredil_a $2 $3 $4",
"matrix-msg-page-created": "$1 je ustvaril_a $2 $3 $4",
"matrix-msg-page-deleted": "$1 je izbrisal_a $2 $3 (izbrisanih $4 redakcij)",
"matrix-msg-page-undeleted-revs": "redakcije za",
"matrix-msg-page-undeleted": "$1 je odizbrisal_a $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 je spremenil_a vidnost $2 redakcij strani $3",
"matrix-msg-page-protect": "$1 je spremenil_a zaščito $2 $3 ($4)",
"matrix-msg-page-moved": "$1 je prestavil_a $2 na $3 $4 $5",
"matrix-msg-user-registered": "Registracija $1",
"matrix-msg-user-block-timeformat": "d. F Y, H:i",
"matrix-msg-user-block": "$1 je blokiral_a $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 je odblokiral_a $2",
"matrix-msg-user-groups-changed": "$1 je spremenil_a pravice $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "nova različica datoteke",
"matrix-msg-file-upload": "$1 je naložil_a $2 $3 $4 ($5, $6&nbsp;×&nbsp;$7, $8)",
"matrix-msg-file-delete": "$1 je izbrisal_a različico datoteke $2 $3",
"matrix-msg-file-undelete": "$1 je obnovil_a nekaj različic datoteke $2 $3",
"matrix-msg-import": "$1 je uvozil_a $2 (uvoženih $4/$3 redakcij)",
"matrix-msg-page-merge": "$1 je združil_a redakcije iz $2 v $3",
"matrix-msg-ext-approvedrevs-approved": "$1 je odobril_a novo redakcijo $2 (redakcija $3) uporabnika_ce $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 je od-odobrila odobreno redakcijo za $2",
"matrix-msg-ext-approvedrevs-approved-file": "$1 je odobril_a novo različico datoteke $2 ($3) uporabnika_ce $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 je od-odobrila odobreno redakcijo datoteke za $2",
"matrix-msg-user-rename": "$1 je preimenoval_a uporabnika $2 v $3"
}
-37
View File
@@ -1,37 +0,0 @@
{
"@metadata": {
"authors": [
"AhmedG612"
]
},
"matrix-desc": "Waxay u dirtaa farriimo kanaalka Matrix marka ay dhacaan dhacdooyin gaar ah",
"matrix-talk": "t",
"matrix-contribs": "c",
"matrix-diff": "Kala duwanaansho",
"matrix-minor": "(m)",
"matrix-msg-page-edited": "$1 ayaa wax ka beddelay $2 $3 $4",
"matrix-msg-page-created": "$1 ayaa abuuray $2 $3 $4",
"matrix-msg-page-deleted": "$1 ayaa tirtiray $2 $3 ($4 wax ka beddel ayaa la tirtiray)",
"matrix-msg-page-undeleted-revs": "dib u eegis loogu talagalay",
"matrix-msg-page-undeleted": "$1 ayaa dib u soo celiyay $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 ayaa beddelay muuqaalka $2 wax ka beddel ee $3",
"matrix-msg-page-protect": "$1 ayaa beddelay ilaalinta $2 $3 ($4)",
"matrix-msg-page-moved": "$1 ayaa u wareejiyay $2 ilaa $3 $4 $5",
"matrix-msg-user-registered": "$1 ayaa is diiwaangeliyay",
"matrix-msg-user-block-timeformat": "d F Y H:i",
"matrix-msg-user-block": "$1 ayaa xannibay $2 $3 ($4)",
"matrix-msg-user-block-partial": "$1 ayaa qayb ahaan xannibay $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 ayaa ka qaaday xannibaadda $2",
"matrix-msg-user-groups-changed": "$1 ayaa beddelay xuquuqaha $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "nooc cusub oo ah",
"matrix-msg-file-upload": "$1 ayaa soo geliyay $2 $3 $4 ($5, $6x$7, $8)",
"matrix-msg-file-delete": "$1 ayaa tirtiray nooc ka mid ah faylka $2 $3",
"matrix-msg-file-undelete": "$1 ayaa dib u soo celiyay qaar ka mid ah noocyadii faylka $2 $3",
"matrix-msg-import": "$1 ayaa soo geliyay $2 (waxaa la soo geliyay $4/$3 wax ka beddel)",
"matrix-msg-page-merge": "$1 ayaa isku daray wax ka beddeladii $2 una gudbiyay $3",
"matrix-msg-ext-approvedrevs-approved": "$1 ayaa oggolaaday nooc cusub oo wax ka beddel ah $2 (wax ka beddelka $3) oo ka yimid isticmaale $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 ayaa ka noqday oggolaanshihii noocii la ansixiyay ee $2",
"matrix-msg-ext-approvedrevs-approved-file": "$1 ayaa oggolaaday nooc cusub oo wax ka beddel faylka $2 ($3) oo ka yimid isticmaale $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 ayaa ka noqday oggolaanshihii noocii faylka ee la ansixiyay ee $2",
"matrix-msg-user-rename": "$1 ayaa magaca isticmaale $2 u beddelay $3"
}
-36
View File
@@ -1,36 +0,0 @@
{
"@metadata": {
"authors": [
"KockaAdmiralac",
"Milicevic01"
]
},
"matrix-desc": "Шаље поруке на Matrix канал када се десе одређени догађаји",
"matrix-talk": "р",
"matrix-contribs": "д",
"matrix-diff": "разл",
"matrix-minor": "(м)",
"matrix-msg-page-edited": "$1 је уредио/ла $2 $3 $4",
"matrix-msg-page-created": "$1 је направио/ла $2 $3 $4",
"matrix-msg-page-deleted": "$1 је обрисао/ла $2 $3 ($4 измена обрисано)",
"matrix-msg-page-undeleted-revs": "измене за",
"matrix-msg-page-undeleted": "$1 је вратио/ла $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 је променио/ла видљивост измене $2 на $3",
"matrix-msg-page-protect": "$1 је променио/ла подешавања заштите $2 $3 ($4)",
"matrix-msg-page-moved": "$1 је преместио/ла $2 на $3 $4 $5",
"matrix-msg-user-registered": "$1 се регистровао/ла",
"matrix-msg-user-block": "$1 је блокирао/ла $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 је деблокирао/ла $2",
"matrix-msg-user-groups-changed": "$1 је променио/ла права $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "нову верзију",
"matrix-msg-file-upload": "$1 је отпремио/ла $2 $3 $4 ($5, $6x$7, $8)",
"matrix-msg-file-delete": "$1 је обрисао/ла верзију датотеке $2 $3",
"matrix-msg-file-undelete": "$1 је вратио/ла поједине верзије датотеке $2 $3",
"matrix-msg-import": "$1 је увезао/ла $2 (увезено $4/$3 измена)",
"matrix-msg-page-merge": "$1 је спојио/ла измене из $2 у $3",
"matrix-msg-ext-approvedrevs-approved": "$1 је одобрио/ла нову измену $2 (измена $3) корисника $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 је поништио/ла одобрену измену за $2",
"matrix-msg-ext-approvedrevs-approved-file": "$1 је одобрио/ла нову верзију датотеке $2 ($3) корисника $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 је поништио/ла одобрену верзију датотеке $2",
"matrix-msg-user-rename": "$1 је преименовао/ла корисника $2 у $3"
}
-35
View File
@@ -1,35 +0,0 @@
{
"@metadata": {
"authors": [
"KockaAdmiralac"
]
},
"matrix-desc": "Šalje poruke na Matrix kanal kada se dese određeni događaji",
"matrix-talk": "r",
"matrix-contribs": "d",
"matrix-diff": "razl",
"matrix-minor": "(m)",
"matrix-msg-page-edited": "$1 je uredio/-la $2 $3 $4",
"matrix-msg-page-created": "$1 je napravio/-la $2 $3 $4",
"matrix-msg-page-deleted": "$1 je obrisao/-la $2 $3 ($4 izmena obrisano)",
"matrix-msg-page-undeleted-revs": "izmene za",
"matrix-msg-page-undeleted": "$1 je vratio/-la $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 je promenio/-la vidljivost $2 izmena na $3",
"matrix-msg-page-protect": "$1 je promenio/-la podešavanja zaštite na $2 $3 ($4)",
"matrix-msg-page-moved": "$1 je pomerio/-la $2 na $3 $4 $5",
"matrix-msg-user-registered": "$1 se registrovao/-la",
"matrix-msg-user-block": "$1 je blokirao/-la $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 je deblokirao/-la $2",
"matrix-msg-user-groups-changed": "$1 je promenio/-la prava od $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "novu verziju",
"matrix-msg-file-upload": "$1 je otpremio/-la $2 $3 $4 ($5, $6x$7, $8)",
"matrix-msg-file-delete": "$1 je obrisao/-la verziju datoteke $2 $3",
"matrix-msg-file-undelete": "$1 je vratio/-la pojedine verzije datoteke $2 $3",
"matrix-msg-import": "$1 je uvezao/-la $2 (uvezeno $4/$3 izmena)",
"matrix-msg-page-merge": "$1 je spojio/-la izmene iz $2 u $3",
"matrix-msg-ext-approvedrevs-approved": "$1 je odobrio/-la novu izmenu $2 (izmena $3) od korisnika $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 je poništio/-la odobrenje izmene $2",
"matrix-msg-ext-approvedrevs-approved-file": "$1 je odobrio/-la novu izmenu datoteke $2 ($3) od korisnika $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 je poništio/-la odobrenje izmene datoteke $2",
"matrix-msg-user-rename": "$1 je preimenovao/-la korisnika $2 u $3"
}
-36
View File
@@ -1,36 +0,0 @@
{
"@metadata": {
"authors": [
"Sabelöga",
"Stefan2255"
]
},
"matrix-desc": "Skickar meddelanden till en Matrix-kanal när vissa händelser sker",
"matrix-talk": "t",
"matrix-contribs": "c",
"matrix-diff": "skillnad",
"matrix-minor": "(m)",
"matrix-msg-page-edited": "$1 redigerade $2 $3 $4",
"matrix-msg-page-created": "$1 skapade $2 $3 $4",
"matrix-msg-page-deleted": "$1 raderade $2 $3 ( $4 sidvisioner raderade)",
"matrix-msg-page-undeleted-revs": "sidversioner för",
"matrix-msg-page-undeleted": "$1 återställde $2 $3 $4",
"matrix-msg-rev-visibility-changed": "$1 ändrade synligheten för $2 sidversioner på $3",
"matrix-msg-page-protect": "$1 ändrade skrivskydd av $2 $3 ($4)",
"matrix-msg-page-moved": "$1 flyttade $2 till $3 $4 $5",
"matrix-msg-user-registered": "$1 registrerade",
"matrix-msg-user-block": "$1 blockerade $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 avblockerade $2",
"matrix-msg-user-groups-changed": "$1 ändrade rättigheter för $2 $3 ($4) ($5)",
"matrix-msg-file-upload-new": "ny version av",
"matrix-msg-file-upload": "$1 laddade upp $2 $3 $4 ($5, $6x$7, $8)",
"matrix-msg-file-delete": "$1 raderad en version av filen $2 $3",
"matrix-msg-file-undelete": "$1 återställde några versioner av filen $2 $3",
"matrix-msg-import": "$1 importerade $2 (importerade $4/$3 sidversioner)",
"matrix-msg-page-merge": "$1 sammanfogade sidversioner från $2 till $3",
"matrix-msg-ext-approvedrevs-approved": "$1 godkände en ny sidversion av $2 (sidversion $3) från användare $4",
"matrix-msg-ext-approvedrevs-unapproved": "$1 drog in godkännandet av sidversionen för $2",
"matrix-msg-ext-approvedrevs-approved-file": "$1 godkände en ny filrevision av $2 ($3) från användare $4",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1 drog in godkännandet för filrevisionen för $2",
"matrix-msg-user-rename": "$1 bytte namn på användare $2 till $3"
}
-21
View File
@@ -1,21 +0,0 @@
{
"@metadata": {
"authors": [
"Tbodt"
]
},
"matrix-talk": "tk",
"matrix-contribs": "pl",
"matrix-diff": "ante",
"matrix-minor": "(lili)",
"matrix-msg-page-edited": "$1 li ante e lipu $2 $3 $4",
"matrix-msg-page-created": "$1 li pali e lipu $2 $3 $4",
"matrix-msg-page-deleted": "$1 li weka e lipu $2 $3 (lipu li ante lon tenpo $4)",
"matrix-msg-page-undeleted": "$1 li lon sin e lipu $2 $3 $4",
"matrix-msg-page-moved": "$1 li ante e nimi lipu $2 tawa nimi $3 $4 $5",
"matrix-msg-user-registered": "$1 li kama lon",
"matrix-msg-user-block": "$1 li ken ala e $2 $3 ($4)",
"matrix-msg-user-unblock": "$1 li ken sin e $2",
"matrix-msg-user-groups-changed": "$1 li ante e ken jan lon $2 $3 ($4) ($5)",
"matrix-msg-user-rename": "$1 li ante e nimi jan $2 tawa nimi $3"
}
-37
View File
@@ -1,37 +0,0 @@
{
"@metadata": {
"authors": [
"Asma",
"Hedda",
"Joseph"
]
},
"matrix-desc": "Belirli olaylar gerçekleştiğinde bir Matrix kanalına mesaj gönderir",
"matrix-talk": "m",
"matrix-contribs": "k",
"matrix-diff": "fark",
"matrix-minor": "(k)",
"matrix-msg-page-edited": "$1, $2 $3 $4 sayfasını düzenledi",
"matrix-msg-page-created": "$1, $2 $3 $4 sayfasını oluşturdu",
"matrix-msg-page-deleted": "$1, $3 sebebiyle $2 sayfasını sildi ($4 değişiklik silindi)",
"matrix-msg-page-undeleted-revs": "şunun için değişiklikler:",
"matrix-msg-page-undeleted": "$1, $2 $3 $4 sayfasını silemedi",
"matrix-msg-rev-visibility-changed": "$1, $3 sayfasındaki $2 değişikliğin görünürlüğünü değiştirdi",
"matrix-msg-page-protect": "$1, $2 sayfasının korunmasını $3 ($4) sebebiyle değiştirdi",
"matrix-msg-page-moved": "$1, $2 sayfasını $4 $5 sebebiyle $3 olacak şekildi taşıdı",
"matrix-msg-user-registered": "$1 kayıt oldu",
"matrix-msg-user-block": "$1, $3 ($4) sebebiyle $2 kullanıcısını engelledi",
"matrix-msg-user-unblock": "$1, $2 kullanıcısının engelini kaldırdı",
"matrix-msg-user-groups-changed": "$1, $3 ($4) ($5) sebebiyle $2 kullanıcısının haklarını değiştirdi",
"matrix-msg-file-upload-new": "şunun yeni sürümü:",
"matrix-msg-file-upload": "$1, $2 $3 $4 ($5, $6x$7, $8) yükledi",
"matrix-msg-file-delete": "$1, $2 $3 dosyasının bir sürümünü sildi",
"matrix-msg-file-undelete": "$1, $2 $3 dosyasının bazı sürümlerini geri yükledi",
"matrix-msg-import": "$1, $2 ice aktardı ($4 içe aktarılan/$3 revizyon)",
"matrix-msg-page-merge": "$1, $2 ile $3 için revizyonları birleştirdi",
"matrix-msg-ext-approvedrevs-approved": "$1, $4 kullanıcısından $2 (değişiklik $3) için yapılan yeni bir değişikliği onayladı",
"matrix-msg-ext-approvedrevs-unapproved": "$1, $2 için yapılan onaylı değişikliği reddetti",
"matrix-msg-ext-approvedrevs-approved-file": "$1, $4 kullanıcısı tarafından $2 ($3) için yapılan yeni bir dosya değişikliğini onayladı",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1, $2 için onaylanan değişikliği reddetti",
"matrix-msg-user-rename": "$1, $2 kullanıcısını $3 olarak yeniden adlandırdı"
}
-39
View File
@@ -1,39 +0,0 @@
{
"@metadata": {
"authors": [
"Anterdc99",
"Peterxy12"
]
},
"matrix-desc": "当某些事件发生时向Matrix频道发送消息",
"matrix-userlinks": "$1$2|$3",
"matrix-talk": "讨论",
"matrix-contribs": "贡献",
"matrix-diff": "差异",
"matrix-minor": "(小)",
"matrix-msg-page-edited": "$1编辑了$2、$3$4",
"matrix-msg-page-created": "$1创建了$2、$3$4",
"matrix-msg-page-deleted": "$1删除了$2$3(已删除版本$4",
"matrix-msg-page-undeleted-revs": "版本为",
"matrix-msg-page-undeleted": "$1还原了$2 $3,原因:$4",
"matrix-msg-rev-visibility-changed": "$1更改了在$3上版本$2的可见性",
"matrix-msg-page-protect": "$1更改了$2的保护($4),原因:$3",
"matrix-msg-page-moved": "$1将$2移动到$3,原因:$4,版本链接:$5",
"matrix-msg-user-registered": "$1已注册",
"matrix-msg-user-block-timeformat": "d F Y H:i",
"matrix-msg-user-block": "$1封禁了$2,原因:$3$4",
"matrix-msg-user-block-partial": "$1已部分封禁$2,原因:$3(到期:$4)",
"matrix-msg-user-unblock": "$1解封了$2",
"matrix-msg-user-groups-changed": "$1更改了$2的权限(新增:$4)(移除:$5),原因:$3",
"matrix-msg-file-upload-new": "新版本的",
"matrix-msg-file-upload": "$1上传了$2 $3$5$6x$7$8),原因:$4",
"matrix-msg-file-delete": "$1删除了文件$2的一个版本,原因:$3",
"matrix-msg-file-undelete": "$1恢复了文件$2的一些版本,原因:$3",
"matrix-msg-import": "$1导入了$2(导入了$4/$3个版本)",
"matrix-msg-page-merge": "$1将$2的版本合并到$3",
"matrix-msg-ext-approvedrevs-approved": "$1批准了来自用户$4的$2新版本$3",
"matrix-msg-ext-approvedrevs-unapproved": "$1取消批准$2的已批准版本",
"matrix-msg-ext-approvedrevs-approved-file": "$1批准了来自用户$4的$2的新文件版本($3)",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1取消批准$2已批准的文件版本",
"matrix-msg-user-rename": "$1将用户$2重命名为$3"
}
-37
View File
@@ -1,37 +0,0 @@
{
"@metadata": {
"authors": [
"Kly"
]
},
"matrix-desc": "當某些事件發生時向 Matrix 頻道發送訊息",
"matrix-talk": "討論",
"matrix-contribs": "貢獻",
"matrix-diff": "差異",
"matrix-minor": "m",
"matrix-msg-page-edited": "$1編輯了$2、$3$4",
"matrix-msg-page-created": "$1建立了$2、$3$4",
"matrix-msg-page-deleted": "$1刪除了$2$3(已刪除修訂 $4",
"matrix-msg-page-undeleted-revs": "修訂為",
"matrix-msg-page-undeleted": "$1取消刪除$2 $3,意見:$4",
"matrix-msg-rev-visibility-changed": "$1更改了在$3上修訂$2的可見度",
"matrix-msg-page-protect": "$1更改了$2的保護($4),原因:$3",
"matrix-msg-page-moved": "$1將$2移動到$3,原因:$4,修訂連結:$5",
"matrix-msg-user-registered": "$1已註冊",
"matrix-msg-user-block-timeformat": "d F Y H:i",
"matrix-msg-user-block": "$1封鎖了$2,原因:$3$4",
"matrix-msg-user-block-partial": "$1已部分封鎖$2,原因:$3(到期:$4)",
"matrix-msg-user-unblock": "$1取消封鎖$2",
"matrix-msg-user-groups-changed": "$1更改了$2的權限(新增:$4)(移除:$5),原因:$3",
"matrix-msg-file-upload-new": "新版本的",
"matrix-msg-file-upload": "$1上傳了$2 $3$5$6x$7$8),意見:$4",
"matrix-msg-file-delete": "$1刪除了檔案$2的一個版本,意見:$3",
"matrix-msg-file-undelete": "$1恢復了檔案$2的一些版本,意見:$3",
"matrix-msg-import": "$1匯入了$2(匯入 $4/$3 個修訂)",
"matrix-msg-page-merge": "$1將$2的修訂合併到$3",
"matrix-msg-ext-approvedrevs-approved": "$1批准了來自使用者$4的$2新修訂($3)",
"matrix-msg-ext-approvedrevs-unapproved": "$1取消批准$2的已批准修訂",
"matrix-msg-ext-approvedrevs-approved-file": "$1批准了來自使用者$4的$2新檔案修訂($3)",
"matrix-msg-ext-approvedrevs-unapproved-file": "$1取消批准$2已批准的檔案修訂",
"matrix-msg-user-rename": "$1將使用者$2重新命名為$3"
}
+552
View File
@@ -0,0 +1,552 @@
<?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
*
* @file
* @ingroup Extensions
*/
class DiscordHooks {
/**
* Called when a page is created or edited
* @see https://www.mediawiki.org/wiki/Manual:Hooks/PageSaveComplete
*/
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( $hookName, $wikiPage->getTitle()->getNamespace(), $user ) ) {
return true;
}
if ( $wgDiscordNoBots && $user->isBot() ) {
// Don't continue, this is a bot edit
return true;
}
if ( $wgDiscordNoMinor && $revision->isMinor() ) {
// Don't continue, this is a minor edit
return true;
}
if ( $wgDiscordNoNull && $editResult->isNullEdit() ) {
// Don't continue, this is a null edit
return true;
}
$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';
if ( $isNew ) { // is a new page
$msgKey = 'discord-create';
}
$msg = wfMessage( $msgKey, DiscordUtils::createUserLinks( $user ),
DiscordUtils::createMarkdownLink( $wikiPage->getTitle(), $wikiPage->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
DiscordUtils::createRevisionText( $revision ),
( $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
*/
public static function onArticleDeleteComplete( &$article, User &$user, $reason, $id, $content, LogEntry $logEntry, $archivedRevisionCount ) {
global $wgDiscordNoBots;
$hookName = 'ArticleDeleteComplete';
if ( DiscordUtils::isDisabled( $hookName, $article->getTitle()->getNamespace(), $user ) ) {
return true;
}
if ( $wgDiscordNoBots && $user->isBot() ) {
// Don't continue, this is a bot change
return true;
}
$msg = wfMessage( 'discord-articledelete', DiscordUtils::createUserLinks( $user ),
DiscordUtils::createMarkdownLink( $article->getTitle(), $article->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
( $reason ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $reason ) ) . '`' ) : '' ),
$archivedRevisionCount)->plain();
DiscordUtils::handleDiscord($hookName, $msg);
return true;
}
/**
* Called when a page's revisions are restored
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleUndelete
*/
public static function onArticleUndelete( Title $title, $create, $comment, $oldPageId, $restoredPages ) {
global $wgDiscordNoBots;
$hookName = 'ArticleUndelete';
$user = RequestContext::getMain()->getUser();
if ( DiscordUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
return true;
}
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( '', false, PROTO_CANONICAL ) ),
( $comment ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $comment ) ) . '`' ) : '' ))->plain();
DiscordUtils::handleDiscord($hookName, $msg);
return true;
}
/**
* Called after committing revision visibility changes to the database
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleRevisionVisibilitySet
*/
public static function onArticleRevisionVisibilitySet( &$title, $ids, $visibilityChangeMap ) {
global $wgDiscordNoBots;
$hookName = 'ArticleRevisionVisibilitySet';
$user = RequestContext::getMain()->getUser();
if ( DiscordUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
return true;
}
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( '', false, PROTO_CANONICAL ) ) )->plain();
DiscordUtils::handleDiscord($hookName, $msg);
return true;
}
/**
* Called when a page is protected (or unprotected)
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleProtectComplete
*/
public static function onArticleProtectComplete( &$article, &$user, $protect, $reason ) {
global $wgDiscordNoBots;
$hookName = 'ArticleProtectComplete';
if ( DiscordUtils::isDisabled( $hookName, $article->getTitle()->getNamespace(), $user ) ) {
return true;
}
if ( $wgDiscordNoBots && $user->isBot() ) {
// Don't continue, this is a bot change
return true;
}
$msg = wfMessage( 'discord-articleprotect', DiscordUtils::createUserLinks( $user ),
DiscordUtils::createMarkdownLink( $article->getTitle(), $article->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
( $reason ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $reason ) ) . '`' ) : '' ),
implode(", ", $protect) )->plain();
DiscordUtils::handleDiscord($hookName, $msg);
return true;
}
/**
* Called when a page is moved
* @see https://www.mediawiki.org/wiki/Manual:Hooks/PageMoveComplete
*/
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( $hookName, $old->getNamespace(), $user ) ) {
return true;
}
if ( $wgDiscordNoBots && $user->isBot() ) {
// Don't continue, this is a bot change
return true;
}
$msg = wfMessage( 'discord-titlemove', DiscordUtils::createUserLinks( $user ),
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($hookName, $msg);
return true;
}
/**
* Called when a user is created
* @see https://www.mediawiki.org/wiki/Manual:Hooks/LocalUserCreated
*/
public static function onLocalUserCreated( $user, $autocreated ) {
$hookName = 'LocalUserCreated';
if ( DiscordUtils::isDisabled( $hookName, NULL, $user ) ) {
return true;
}
$msg = wfMessage( 'discord-localusercreated', DiscordUtils::createUserLinks( $user ) )->plain();
DiscordUtils::handleDiscord($hookName, $msg);
return true;
}
/**
* Called when a user is blocked
* @see https://www.mediawiki.org/wiki/Manual:Hooks/BlockIpComplete
*/
public static function onBlockIpComplete( Block $block, User $user ) {
$hookName = 'BlockIpComplete';
if ( DiscordUtils::isDisabled( $hookName, NULL, $user ) ) {
return true;
}
$expiry = $block->getExpiry();
if ($expires = strtotime($expiry)) {
$expiryMsg = sprintf('%s', date( wfMessage( 'discord-blocktimeformat' )->text(), $expires));
} else {
$expiryMsg = $expiry;
}
$msg = wfMessage( 'discord-blockipcomplete', DiscordUtils::createUserLinks( $user ), DiscordUtils::createUserLinks( $block->getTarget() ),
( $block->getReasonComment()->text ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $block->getReasonComment()->text ) ) . '`' ) : '' ),
$expiryMsg )->plain();
DiscordUtils::handleDiscord($hookName, $msg);
return true;
}
/**
* Called when a user is unblocked
* @see https://www.mediawiki.org/wiki/Manual:Hooks/UnblockUserComplete
*/
public static function onUnblockUserComplete( Block $block, User $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($hookName, $msg);
return true;
}
/**
* Called when a user's rights are changed
* @see https://www.mediawiki.org/wiki/Manual:Hooks/UserGroupsChanged
*/
public static function onUserGroupsChanged( User $user, array $added, array $removed, $performer, $reason ) {
$hookName = 'UserGroupsChanged';
if ( DiscordUtils::isDisabled( $hookName, NULL, $performer ) ) {
return true;
}
if ($performer === false) {
// Rights were changed by autopromotion, do nothing
return true;
}
$msg = wfMessage( 'discord-usergroupschanged', DiscordUtils::createUserLinks( $performer ),
DiscordUtils::createUserLinks( $user ),
( $reason ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $reason ) ) . '`' ) : '' ),
( ( count($added) > 0 ) ? ( '+ ' . join(', ', $added) ) : ''),
( ( count($removed) > 0 ) ? ( '- ' . join(', ', $removed) ) : '' ) )->plain();
DiscordUtils::handleDiscord($hookName, $msg);
return true;
}
/**
* Called when a file upload is complete
* @see https://www.mediawiki.org/wiki/Manual:Hooks/UploadComplete
*/
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( $hookName, NS_FILE, $user ) ) {
return true;
}
if ( $wgDiscordNoBots && $user->isBot() ) {
// Don't continue, this is a bot change
return true;
}
$comment = $lf->getDescription();
$isNewRevision = count($lf->getHistory()) > 0;
$msg = wfMessage( 'discord-uploadcomplete', DiscordUtils::createUserLinks( $user ),
( $isNewRevision ? wfMessage( 'discord-uploadnewver' )->text() : '' ),
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($hookName, $msg);
return true;
}
/**
* Called when a file is deleted
* @see https://www.mediawiki.org/wiki/Manual:Hooks/FileDeleteComplete
*/
public static function onFileDeleteComplete( $file, $oldimage, $article, $user, $reason ) {
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;
}
if ( $article ) {
// Entire page was deleted, onArticleDeleteComplete will handle this
return true;
}
$msg = wfMessage( 'discord-filedeletecomplete', DiscordUtils::createUserLinks( $user ),
DiscordUtils::createMarkdownLink( $file->getName(), $file->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
( $reason ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $reason ) ) . '`' ) : '' ) )->plain();
DiscordUtils::handleDiscord($hookName, $msg);
return true;
}
/**
* Called when a file is restored
* @see https://www.mediawiki.org/wiki/Manual:Hooks/FileUndeleteComplete
*/
public static function onFileUndeleteComplete( $title, $fileVersions, $user, $reason ) {
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( '', 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 = $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;
}
}
-716
View File
@@ -1,716 +0,0 @@
<?php
namespace MediaWiki\Extension\Matrix;
use ForeignTitle;
use ImagePage;
use LocalFile;
use ManualLogEntry;
use MediaWiki\Auth\Hook\LocalUserCreatedHook;
use MediaWiki\Block\DatabaseBlock;
use MediaWiki\Context\RequestContext;
use MediaWiki\Hook\AfterImportPageHook;
use MediaWiki\Hook\ArticleMergeCompleteHook;
use MediaWiki\Hook\ArticleRevisionVisibilitySetHook;
use MediaWiki\Hook\BlockIpCompleteHook;
use MediaWiki\Hook\FileDeleteCompleteHook;
use MediaWiki\Hook\FileUndeleteCompleteHook;
use MediaWiki\Hook\PageMoveCompleteHook;
use MediaWiki\Hook\UnblockUserCompleteHook;
use MediaWiki\Hook\UploadCompleteHook;
use MediaWiki\Linker\LinkTarget;
use MediaWiki\MediaWikiServices;
use MediaWiki\Page\Hook\ArticleProtectCompleteHook;
use MediaWiki\Page\Hook\PageDeleteCompleteHook;
use MediaWiki\Page\Hook\PageUndeleteCompleteHook;
use MediaWiki\Page\ProperPageIdentity;
use MediaWiki\Parser\Parser;
use MediaWiki\Permissions\Authority;
use MediaWiki\RenameUser\Hook\RenameUserCompleteHook;
use MediaWiki\Revision\RevisionRecord;
use MediaWiki\Storage\EditResult;
use MediaWiki\Storage\Hook\PageSaveCompleteHook;
use MediaWiki\Title\Title;
use MediaWiki\User\Hook\UserGroupsChangedHook;
use MediaWiki\User\User;
use MediaWiki\User\UserGroupMembership;
use MediaWiki\User\UserIdentity;
use UploadBase;
use WikiFilePage;
use WikiPage;
/**
* Hooks for the Matrix extension
*
* @file
* @ingroup Extensions
*/
class MatrixHooks implements
PageSaveCompleteHook,
PageDeleteCompleteHook,
ArticleRevisionVisibilitySetHook,
ArticleProtectCompleteHook,
PageMoveCompleteHook,
LocalUserCreatedHook,
BlockIpCompleteHook,
UnblockUserCompleteHook,
UserGroupsChangedHook,
UploadCompleteHook,
FileDeleteCompleteHook,
FileUndeleteCompleteHook,
AfterImportPageHook,
ArticleMergeCompleteHook,
RenameUserCompleteHook,
PageUndeleteCompleteHook
{
private MatrixMessageSender $messageSender;
public function __construct( MatrixMessageSender $messageSender ) {
$this->messageSender = $messageSender;
}
/**
* @param WikiPage $wikiPage
* @param UserIdentity $userIdentity
* @param string $summary
* @param int $flags
* @param RevisionRecord $revisionRecord
* @param EditResult $editResult
* @return bool
*/
public function onPageSaveComplete(
$wikiPage,
$userIdentity,
$summary,
$flags,
$revisionRecord,
$editResult
): bool {
global $wgMatrixNoBots, $wgMatrixNoMinor, $wgMatrixNoNull;
$hookName = 'PageSaveComplete';
$user = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $userIdentity );
if ( MatrixUtils::isDisabled( $hookName, $wikiPage->getTitle()->getNamespace(), $user ) ) {
return true;
}
$isNew = $editResult->isNew();
if (
( $wgMatrixNoBots && $user->isBot() ) ||
( $wgMatrixNoMinor && $revisionRecord->isMinor() ) ||
( $wgMatrixNoNull && $editResult->isNullEdit() ) ||
( $isNew && $wikiPage->getNamespace() === NS_FILE )
) {
return true;
}
$msgKey = 'matrix-msg-page-edited';
if ( $isNew ) {
$msgKey = 'matrix-msg-page-created';
}
$msg = wfMessage( $msgKey, MatrixUtils::createUserLinks( $user ),
MatrixUtils::createLink( $wikiPage->getTitle(),
$wikiPage->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
MatrixUtils::createRevisionText( $revisionRecord ),
( $summary ? ( '`' . MatrixUtils::sanitiseText(
MatrixUtils::truncateText( $summary ) ) . '`' ) : '' ) )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
public function onPageDeleteComplete(
ProperPageIdentity $page,
Authority $deleter,
string $reason,
int $pageID,
RevisionRecord $deletedRev,
ManualLogEntry $logEntry,
int $archivedRevisionCount
): bool {
global $wgMatrixNoBots;
$hookName = 'PageDeleteComplete';
$user = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $deleter->getUser() );
$page = MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $page );
if ( MatrixUtils::isDisabled( $hookName, $page->getNamespace(), $user ) ) {
return true;
}
if ( $wgMatrixNoBots && $user->isBot() ) {
// Don't continue, this is a bot change
return true;
}
$msg = wfMessage( 'matrix-msg-page-deleted', MatrixUtils::createUserLinks( $user ),
MatrixUtils::createLink( $page->getTitle(),
$page->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
( $reason ? ( '`' . MatrixUtils::sanitiseText( MatrixUtils::truncateText( $reason ) ) . '`' ) : '' ),
$archivedRevisionCount )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
public function onPageUndeleteComplete(
ProperPageIdentity $page,
Authority $restorer,
string $reason,
RevisionRecord $restoredRev,
ManualLogEntry $logEntry,
int $restoredRevisionCount,
bool $created,
array $restoredPageIds
): void {
global $wgMatrixNoBots;
$hookName = 'PageUndeleteComplete';
$user = RequestContext::getMain()->getUser();
if ( MatrixUtils::isDisabled( $hookName, $page->getNamespace(), $user ) ) {
return;
}
if ( $wgMatrixNoBots && $user->isBot() ) {
// Don't continue, this is a bot change
return;
}
$title = MediaWikiServices::getInstance()->getTitleFactory()->newFromPageIdentity( $page );
$msg = wfMessage( 'matrix-msg-page-undeleted', MatrixUtils::createUserLinks( $user ),
( $created ? '' : wfMessage( 'matrix-msg-page-undeleted-revs' )->inContentLanguage()->text() ),
MatrixUtils::createLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ),
( $reason ? ( '`' . MatrixUtils::sanitiseText(
MatrixUtils::truncateText( $reason ) ) . '`' ) : '' ) )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
}
/**
* @param Title $title
* @param int[] $ids
* @param array $visibilityChangeMap
* @return bool
*/
public function onArticleRevisionVisibilitySet( $title, $ids, $visibilityChangeMap ): bool {
global $wgMatrixNoBots;
$hookName = 'ArticleRevisionVisibilitySet';
$user = RequestContext::getMain()->getUser();
if ( MatrixUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
return true;
}
if ( $wgMatrixNoBots && $user->isBot() ) {
// Don't continue, this is a bot change
return true;
}
$msg = wfMessage( 'matrix-msg-rev-visibility-changed', MatrixUtils::createUserLinks( $user ),
count( $visibilityChangeMap ),
MatrixUtils::createLink( $title,
$title->getFullURL( '', false, PROTO_CANONICAL ) ) )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param WikiPage $wikiPage
* @param User $user
* @param array $protect
* @param string $reason
* @return bool
*/
public function onArticleProtectComplete( $wikiPage, $user, $protect, $reason ): bool {
global $wgMatrixNoBots;
$hookName = 'ArticleProtectComplete';
if ( MatrixUtils::isDisabled( $hookName, $wikiPage->getTitle()->getNamespace(), $user ) ) {
return true;
}
if ( $wgMatrixNoBots && $user->isBot() ) {
// Don't continue, this is a bot change
return true;
}
$msg = wfMessage( 'matrix-msg-page-protect', MatrixUtils::createUserLinks( $user ),
MatrixUtils::createLink( $wikiPage->getTitle(),
$wikiPage->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
( $reason ? ( '`' . MatrixUtils::sanitiseText( MatrixUtils::truncateText( $reason ) ) . '`' ) : '' ),
implode( ", ", $protect ) )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param LinkTarget $old
* @param LinkTarget $new
* @param UserIdentity $userIdentity
* @param int $pageid
* @param int $redirid
* @param string $reason
* @param RevisionRecord $revision
* @return bool
*/
public function onPageMoveComplete(
$old,
$new,
$userIdentity,
$pageid,
$redirid,
$reason,
$revision
): bool {
global $wgMatrixNoBots;
$hookName = 'PageMoveComplete';
$user = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $userIdentity );
if ( MatrixUtils::isDisabled( $hookName, $old->getNamespace(), $user ) ) {
return true;
}
if ( $wgMatrixNoBots && $user->isBot() ) {
// Don't continue, this is a bot change
return true;
}
$msg = wfMessage( 'matrix-msg-page-moved', MatrixUtils::createUserLinks( $user ),
MatrixUtils::createLink( $old,
Title::castFromLinkTarget( $old )->getFullURL( '', false, PROTO_CANONICAL ) ),
MatrixUtils::createLink( $new,
Title::castFromLinkTarget( $new )->getFullURL( '', false, PROTO_CANONICAL ) ),
( $reason ? ( '`' . MatrixUtils::sanitiseText( MatrixUtils::truncateText( $reason ) ) . '`' ) : '' ),
MatrixUtils::createRevisionText( $revision ) )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param User $user
* @param bool $autocreated
* @return bool
*/
public function onLocalUserCreated( $user, $autocreated ): bool {
$hookName = 'LocalUserCreated';
if ( MatrixUtils::isDisabled( $hookName, null, $user ) ) {
return true;
}
if ( $user->isTemp() ) {
return true;
}
$msg = wfMessage( 'matrix-msg-user-registered',
MatrixUtils::createUserLinks( $user ) )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param DatabaseBlock $block
* @param User $user
* @param ?DatabaseBlock $priorBlock
* @return bool
*/
public function onBlockIpComplete( $block, $user, $priorBlock ): bool {
$hookName = 'BlockIpComplete';
if ( MatrixUtils::isDisabled( $hookName, null, $user ) ) {
return true;
}
$expiry = $block->getExpiry();
$expiryAsUnix = strtotime( $expiry );
if ( $expiryAsUnix ) {
$expiryMsg = sprintf( '%s',
date( wfMessage( 'matrix-msg-user-block-timeformat' )->inContentLanguage()->text(), $expiryAsUnix ) );
} else {
$expiryMsg = $expiry;
}
$target = $block->getTargetUserIdentity();
if ( $target === null ) {
$target = $block->getTargetName();
}
$msgName = $block->isSitewide() ? 'matrix-msg-user-block' : 'matrix-msg-user-block-partial';
$msg = wfMessage( $msgName, MatrixUtils::createUserLinks( $user ),
MatrixUtils::createUserLinks( $target ),
( $block->getReasonComment()->text ? ( '`' . MatrixUtils::sanitiseText(
MatrixUtils::truncateText( $block->getReasonComment()->text ) ) . '`' ) : '' ),
$expiryMsg )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param DatabaseBlock $block
* @param User $user
* @return bool
*/
public function onUnblockUserComplete( $block, $user ): bool {
$hookName = 'UnblockUserComplete';
if ( MatrixUtils::isDisabled( $hookName, null, $user ) ) {
return true;
}
$target = $block->getTargetUserIdentity();
if ( $target === null ) {
$target = $block->getTargetName();
}
$msg = wfMessage( 'matrix-msg-user-unblock', MatrixUtils::createUserLinks( $user ),
MatrixUtils::createUserLinks( $target ) )->inContentLanguage()->text();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param User|UserIdentity $user
* @param string[] $added
* @param string[] $removed
* @param User|false $performer
* @param string|false $reason
* @param UserGroupMembership[] $oldUGMs
* @param UserGroupMembership[] $newUGMs
* @return bool
*/
public function onUserGroupsChanged( $user, $added, $removed, $performer, $reason, $oldUGMs, $newUGMs ): bool {
$hookName = 'UserGroupsChanged';
if ( MatrixUtils::isDisabled( $hookName, null, $performer ) ) {
return true;
}
if ( $performer === false ) {
// Rights were changed by autopromotion, do nothing
return true;
}
$msg = wfMessage( 'matrix-msg-user-groups-changed', MatrixUtils::createUserLinks( $performer ),
MatrixUtils::createUserLinks( $user ),
( $reason ? ( '`' . MatrixUtils::sanitiseText( MatrixUtils::truncateText( $reason ) ) . '`' ) : '' ),
( ( count( $added ) > 0 ) ? ( '+ ' . implode( ', ', $added ) ) : '' ),
( ( count( $removed ) > 0 ) ? ( '- ' . implode( ', ', $removed ) ) : '' ) )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param UploadBase $uploadBase
* @return bool
*/
public function onUploadComplete( $uploadBase ): bool {
global $wgMatrixNoBots;
$hookName = 'UploadComplete';
$lf = $uploadBase->getLocalFile();
$user = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $lf->getUploader() );
if ( MatrixUtils::isDisabled( $hookName, NS_FILE, $user ) ) {
return true;
}
if ( $wgMatrixNoBots && $user->isBot() ) {
// Don't continue, this is a bot change
return true;
}
$comment = $lf->getDescription();
$isNewRevision = count( $lf->getHistory() ) > 0;
$msg = wfMessage( 'matrix-msg-file-upload', MatrixUtils::createUserLinks( $user ),
( $isNewRevision ? wfMessage( 'matrix-msg-file-upload-new' )->inContentLanguage()->text() : '' ),
MatrixUtils::createLink( $lf->getName(),
$lf->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
( $comment ? ( '`' . MatrixUtils::sanitiseText( MatrixUtils::truncateText( $comment ) ) . '`' ) : '' ),
MatrixUtils::formatBytes( $lf->getSize() ),
$lf->getWidth(),
$lf->getHeight(),
$lf->getMimeType() )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param LocalFile $file
* @param string|null $oldimage
* @param WikiFilePage|null $article
* @param User $user
* @param string $reason
* @return bool
*/
public function onFileDeleteComplete( $file, $oldimage, $article, $user, $reason ): bool {
global $wgMatrixNoBots;
$hookName = 'FileDeleteComplete';
if ( MatrixUtils::isDisabled( $hookName, NS_FILE, $user ) ) {
return true;
}
if ( $wgMatrixNoBots && $user->isBot() ) {
// Don't continue, this is a bot change
return true;
}
if ( $article ) {
// Entire page was deleted, onArticleDeleteComplete will handle this
return true;
}
$msg = wfMessage( 'matrix-msg-file-delete', MatrixUtils::createUserLinks( $user ),
MatrixUtils::createLink( $file->getName(),
$file->getTitle()->getFullURL( '', false, PROTO_CANONICAL ) ),
( $reason ? ( '`' . MatrixUtils::sanitiseText(
MatrixUtils::truncateText( $reason ) ) . '`' ) : '' ) )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param Title $title
* @param int[] $fileVersions
* @param User $user
* @param string $reason
* @return bool
*/
public function onFileUndeleteComplete( $title, $fileVersions, $user, $reason ): bool {
global $wgMatrixNoBots;
$hookName = 'FileUndeleteComplete';
if ( MatrixUtils::isDisabled( $hookName, NS_FILE, $user ) ) {
return true;
}
if ( $wgMatrixNoBots && $user->isBot() ) {
// Don't continue, this is a bot change
return true;
}
$msg = wfMessage( 'matrix-msg-file-undelete', MatrixUtils::createUserLinks( $user ),
MatrixUtils::createLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ),
( $reason ? ( '`' . MatrixUtils::sanitiseText(
MatrixUtils::truncateText( $reason ) ) . '`' ) : '' ) )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param Title $title
* @param ForeignTitle $foreignTitle
* @param int $revCount
* @param int $sRevCount
* @param array $pageInfo
* @return bool
*/
public function onAfterImportPage( $title, $foreignTitle, $revCount, $sRevCount, $pageInfo ): bool {
global $wgMatrixNoBots;
$hookName = 'AfterImportPage';
$user = RequestContext::getMain()->getUser();
if ( MatrixUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
return true;
}
if ( $wgMatrixNoBots && $user->isBot() ) {
// Don't continue, this is a bot
return true;
}
$msg = wfMessage( 'matrix-msg-import', MatrixUtils::createUserLinks( $user ),
MatrixUtils::createLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ),
$revCount, $sRevCount )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param Title $targetTitle
* @param Title $destTitle
* @return bool
*/
public function onArticleMergeComplete( $targetTitle, $destTitle ): bool {
global $wgMatrixNoBots;
$hookName = 'ArticleMergeComplete';
$user = RequestContext::getMain()->getUser();
if ( MatrixUtils::isDisabled( $hookName, $destTitle->getNamespace(), $user ) ) {
return true;
}
if ( $wgMatrixNoBots && $user->isBot() ) {
// Don't continue, this is a bot
return true;
}
$msg = wfMessage( 'matrix-msg-page-merge', MatrixUtils::createUserLinks( $user ),
MatrixUtils::createLink( $targetTitle, $targetTitle->getFullURL( '', false, PROTO_CANONICAL ) ),
MatrixUtils::createLink( $destTitle,
$destTitle->getFullURL( '', false, PROTO_CANONICAL ) ) )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param null $output
* @param Title $title
* @param int $rev_id
* @param mixed $content
* @return bool
* @see https://github.com/wikimedia/mediawiki-extensions-ApprovedRevs/blob/REL1_45/includes/ApprovedRevs.php#L602
*/
public function onApprovedRevsRevisionApproved( $output, $title, $rev_id, $content ): bool {
global $wgMatrixNoBots;
$hookName = 'ApprovedRevsRevisionApproved';
$user = RequestContext::getMain()->getUser();
if ( MatrixUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
return true;
}
if ( $wgMatrixNoBots && $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 = MatrixUtils::createUserLinks( $rev->getUser( RevisionRecord::RAW ) );
$msg = wfMessage( 'matrix-msg-ext-approvedrevs-approved', MatrixUtils::createUserLinks( $user ),
MatrixUtils::createLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ),
MatrixUtils::createLink( $rev_id, $revLink ),
$revAuthor )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param null $output
* @param Title $title
* @param mixed $content
* @return bool
* @see https://github.com/wikimedia/mediawiki-extensions-ApprovedRevs/blob/REL1_45/includes/ApprovedRevs.php#L712
*/
public function onApprovedRevsRevisionUnapproved( $output, $title, $content ): bool {
global $wgMatrixNoBots;
$hookName = 'ApprovedRevsRevisionUnapproved';
$user = RequestContext::getMain()->getUser();
if ( MatrixUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
return true;
}
if ( $wgMatrixNoBots && $user->isBot() ) {
// Don't continue, this is a bot
return true;
}
$msg = wfMessage( 'matrix-msg-ext-approvedrevs-unapproved', MatrixUtils::createUserLinks( $user ),
MatrixUtils::createLink( $title,
$title->getFullURL( '', false, PROTO_CANONICAL ) ) )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param Parser $parser
* @param Title $title
* @param string $timestamp
* @param string $sha1
* @return bool
* @see https://github.com/wikimedia/mediawiki-extensions-ApprovedRevs/blob/REL1_45/includes/ApprovedRevs.php#L827
*/
public function onApprovedRevsFileRevisionApproved( $parser, $title, $timestamp, $sha1 ): bool {
global $wgMatrixNoBots;
$hookName = 'ApprovedRevsFileRevisionApproved';
$user = RequestContext::getMain()->getUser();
if ( MatrixUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
return true;
}
if ( $wgMatrixNoBots && $user->isBot() ) {
// Don't continue, this is a bot
return true;
}
$imagepage = ImagePage::newFromID( $title->getArticleID() );
$displayedFile = $imagepage->getDisplayedFile();
// getFullURL doesn't work quite the same on File classes
$displayedFileUrl = $displayedFile->getCanonicalUrl();
$uploader = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity(
$displayedFile->getUploader() );
$msg = wfMessage( 'matrix-msg-ext-approvedrevs-approved-file', MatrixUtils::createUserLinks( $user ),
MatrixUtils::createLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ),
MatrixUtils::createLink( 'direct', $displayedFileUrl ),
MatrixUtils::createUserLinks( $uploader ) )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param Parser $parser
* @param Title $title
* @return bool
* @see https://github.com/wikimedia/mediawiki-extensions-ApprovedRevs/blob/REL1_45/includes/ApprovedRevs.php#L865
*/
public function onApprovedRevsFileRevisionUnapproved( $parser, $title ): bool {
global $wgMatrixNoBots;
$hookName = 'ApprovedRevsFileRevisionUnapproved';
$user = RequestContext::getMain()->getUser();
if ( MatrixUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
return true;
}
if ( $wgMatrixNoBots && $user->isBot() ) {
// Don't continue, this is a bot
return true;
}
$msg = wfMessage( 'matrix-msg-ext-approvedrevs-unapproved-file', MatrixUtils::createUserLinks( $user ),
MatrixUtils::createLink( $title,
$title->getFullURL( '', false, PROTO_CANONICAL ) ) )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
return true;
}
/**
* @param int $uid
* @param string $old
* @param string $new
* @return void
*/
public function onRenameUserComplete( $uid, $old, $new ): void {
$hookName = 'RenameUserComplete';
$user = RequestContext::getMain()->getUser();
if ( MatrixUtils::isDisabled( $hookName, null, null ) ) {
return;
}
$renamedUserAsTitle = MediaWikiServices::getInstance()->getUserFactory()->newFromName( $new )->getUserPage();
$msg = wfMessage( 'matrix-msg-user-rename', MatrixUtils::createUserLinks( $user ),
"*$old*",
MatrixUtils::createLink( $new,
$renamedUserAsTitle->getFullURL( '', false, PROTO_CANONICAL ) ) )->inContentLanguage()->plain();
$this->messageSender->sendToMatrix( $hookName, $msg );
}
}
-260
View File
@@ -1,260 +0,0 @@
<?php
namespace MediaWiki\Extension\Matrix;
use Exception;
use MediaWiki\Deferred\DeferredUpdates;
use MediaWiki\Http\HttpRequestFactory;
use Wikimedia\Http\MultiHttpClient;
class MatrixMessageSender {
private MultiHttpClient $multiHttpClient;
private ?string $accessToken = null;
private ?string $accessTokenConfigKey = null;
public function __construct( HttpRequestFactory $httpRequestFactory ) {
$this->multiHttpClient = $httpRequestFactory->createMultiClient( [
'connTimeout' => 10,
'reqTimeout' => 10
] );
}
/**
* Sends a message to Matrix, based on the extension's configuration.
* @param string $hookName
* @param string $msg
* @return void
*/
public function sendToMatrix( string $hookName, string $msg ) {
global $wgMatrixEmojis, $wgMatrixUseEmojis, $wgMatrixPrependTimestamp;
$config = $this->getConnectionConfig();
if ( $config === null ) {
return;
}
// Strip whitespace to just one space
$stripped = preg_replace( '/\s+/', ' ', $msg ) ?? $msg;
if ( $wgMatrixPrependTimestamp ) {
$dateFormat = str_replace(
'**',
'',
wfMessage( 'matrix-timestampformat' )->inContentLanguage()->text()
);
$dateString = gmdate( trim( $dateFormat ) );
$stripped = trim( $dateString . ' ' . $stripped );
}
if ( $wgMatrixUseEmojis && isset( $wgMatrixEmojis[$hookName] ) ) {
$stripped = $wgMatrixEmojis[$hookName] . ' ' . $stripped;
}
DeferredUpdates::addCallableUpdate( function () use ( $config, $stripped ) {
$accessToken = $this->getAccessToken(
$config['homeserverUrl'],
$config['user'],
$config['password']
);
if ( $accessToken === null ) {
return;
}
$payload = [
'msgtype' => 'm.text',
'body' => MatrixUtils::toPlainText( $stripped ),
'format' => 'org.matrix.custom.html',
'formatted_body' => MatrixUtils::toMatrixHtml( $stripped ),
];
$reqs = [];
foreach ( $config['rooms'] as $room ) {
$reqs[] = $this->buildMessageRequest(
$config['homeserverUrl'],
$room,
$accessToken,
$payload
);
}
try {
$responses = $this->multiHttpClient->runMulti( $reqs );
foreach ( $responses as $req ) {
$response = $req['response'] ?? null;
if ( !is_array( $response ) ) {
wfDebugLog( 'matrix', 'Matrix send request returned no response.' );
continue;
}
$this->logIfRequestFailed(
'Failed to send Matrix message to room "' . ( $req['matrixRoom'] ?? 'unknown' ) . '"',
$response
);
}
} catch ( Exception $e ) {
wfDebugLog( 'matrix', 'Failed to send Matrix message: ' . $e->getMessage() );
}
} );
}
/**
* @return array{homeserverUrl:string,user:string,password:string,rooms:string[]}|null
*/
private function getConnectionConfig(): ?array {
global $wgMatrixHomeserverURL, $wgMatrixUser, $wgMatrixPassword, $wgMatrixRooms;
if ( !is_string( $wgMatrixHomeserverURL ) || trim( $wgMatrixHomeserverURL ) === '' ) {
wfDebugLog( 'matrix',
'The value of $wgMatrixHomeserverURL is not valid and therefore no messages could be sent.' );
return null;
}
if ( !is_string( $wgMatrixUser ) || trim( $wgMatrixUser ) === '' ) {
wfDebugLog( 'matrix',
'The value of $wgMatrixUser is not valid and therefore no messages could be sent.' );
return null;
}
if ( !is_string( $wgMatrixPassword ) || trim( $wgMatrixPassword ) === '' ) {
wfDebugLog( 'matrix',
'The value of $wgMatrixPassword is not valid and therefore no messages could be sent.' );
return null;
}
$rooms = [];
if ( is_array( $wgMatrixRooms ) ) {
foreach ( $wgMatrixRooms as $room ) {
if ( is_string( $room ) && trim( $room ) !== '' ) {
$rooms[] = trim( $room );
}
}
} elseif ( is_string( $wgMatrixRooms ) && trim( $wgMatrixRooms ) !== '' ) {
$rooms[] = trim( $wgMatrixRooms );
} else {
wfDebugLog( 'matrix',
'The value of $wgMatrixRooms is not valid and therefore no messages could be sent.' );
return null;
}
$rooms = array_values( array_unique( $rooms ) );
if ( $rooms === [] ) {
wfDebugLog( 'matrix',
'The value of $wgMatrixRooms is empty and therefore no messages could be sent.' );
return null;
}
return [
'homeserverUrl' => rtrim( trim( $wgMatrixHomeserverURL ), '/' ),
'user' => trim( $wgMatrixUser ),
'password' => $wgMatrixPassword,
'rooms' => $rooms,
];
}
private function getAccessToken( string $homeserverUrl, string $user, string $password ): ?string {
$configKey = md5( $homeserverUrl . "\n" . $user . "\n" . $password );
if ( $this->accessToken !== null && $this->accessTokenConfigKey === $configKey ) {
return $this->accessToken;
}
try {
$response = $this->multiHttpClient->run(
$this->buildLoginRequest( $homeserverUrl, $user, $password )
);
} catch ( Exception $e ) {
wfDebugLog( 'matrix', 'Failed to log in to Matrix: ' . $e->getMessage() );
return null;
}
if ( $this->logIfRequestFailed( 'Failed to log in to Matrix', $response ) ) {
return null;
}
$responseBody = $response['body'] ?? '';
$data = json_decode( $responseBody, true );
if ( !is_array( $data ) || !isset( $data['access_token'] ) || !is_string( $data['access_token'] ) ) {
wfDebugLog( 'matrix',
'Matrix login did not return a valid access_token. Response body: ' . $responseBody );
return null;
}
$this->accessToken = $data['access_token'];
$this->accessTokenConfigKey = $configKey;
return $this->accessToken;
}
private function buildLoginRequest( string $homeserverUrl, string $user, string $password ): array {
return [
'method' => 'POST',
'url' => $homeserverUrl . '/_matrix/client/r0/login',
'headers' => $this->getJsonHeaders(),
'body' => json_encode( [
'type' => 'm.login.password',
'user' => $user,
'password' => $password,
] )
];
}
private function buildMessageRequest(
string $homeserverUrl,
string $room,
string $accessToken,
array $payload
): array {
return [
'method' => 'PUT',
'url' => $homeserverUrl . '/_matrix/client/r0/rooms/' .
rawurlencode( $room ) . '/send/m.room.message/' . rawurlencode( $this->generateTxnId() ),
'query' => [
'access_token' => $accessToken,
],
'headers' => $this->getJsonHeaders(),
'body' => json_encode( $payload ),
'matrixRoom' => $room,
];
}
private function getJsonHeaders(): array {
return [
'Content-Type' => 'application/json',
'User-Agent' => 'mw-matrix (git.pvv.ntnu.no/Projects/mediawiki-matrix-notifs)',
];
}
private function generateTxnId(): string {
return str_replace( '.', '-', uniqid( 'mw-matrix-', true ) );
}
/**
* @param string $context
* @param array $response
* @return bool True when the request failed
*/
private function logIfRequestFailed( string $context, array $response ): bool {
$code = (int)( $response['code'] ?? 0 );
if ( $code >= 200 && $code < 300 ) {
return false;
}
$error = $response['error'] ?? '';
$reason = $response['reason'] ?? '';
$body = $response['body'] ?? '';
wfDebugLog(
'matrix',
$context . ': HTTP ' . $code .
( $reason !== '' ? ' ' . $reason : '' ) .
( $error !== '' ? ' (' . $error . ')' : '' ) .
( $body !== '' ? ' ' . $body : '' )
);
return true;
}
}
-260
View File
@@ -1,260 +0,0 @@
<?php
namespace MediaWiki\Extension\Matrix;
use MediaWiki\MediaWikiServices;
use MediaWiki\Revision\RevisionRecord;
use MediaWiki\Title\Title;
use MediaWiki\User\User;
use MediaWiki\User\UserIdentity;
class MatrixUtils {
/**
* Checks if criteria is met for this action to be cancelled
* @param string $hook
* @param int|null $ns
* @param User|UserIdentity|null $user
* @return bool
*/
public static function isDisabled(
string $hook, int|null $ns, User|UserIdentity|null $user
): bool {
global $wgMatrixDisabledHooks, $wgMatrixDisabledNS, $wgMatrixDisabledUsers;
if ( is_array( $wgMatrixDisabledHooks ) ) {
if ( in_array( strtolower( $hook ), array_map( 'strtolower', $wgMatrixDisabledHooks ) ) ) {
// Hook is disabled, return true
return true;
}
} else {
wfDebugLog( 'matrix',
'The value of $wgMatrixDisabledHooks is not valid and therefore all hooks are enabled.' );
}
if ( is_array( $wgMatrixDisabledNS ) ) {
if ( $ns !== null ) {
$ns = (int)$ns;
if ( in_array( $ns, $wgMatrixDisabledNS ) ) {
// Namespace is disabled, return true
return true;
}
}
} else {
wfDebugLog( 'matrix',
'The value of $wgMatrixDisabledNS is not valid and therefore all namespaces are enabled.' );
}
if ( is_array( $wgMatrixDisabledUsers ) ) {
if ( $user !== null ) {
if ( $user instanceof UserIdentity ) {
$user = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $user );
}
if ( $user instanceof User ) {
if ( in_array( $user->getName(), $wgMatrixDisabledUsers ) ) {
// User shouldn't trigger a message, return true
return true;
}
}
}
} else {
wfDebugLog( 'matrix',
'The value of $wgMatrixDisabledUsers is not valid and therefore all users can trigger messages.' );
}
return false;
}
/**
* Creates a formatted link.
* @param string $text
* @param string $url
* @return string
*/
public static function createLink( string $text, string $url ): string {
return '<a href="' . self::escapeHtml( self::encodeURL( $url ) ) . '">' .
self::escapeHtml( $text ) . '</a>';
}
/**
* Creates links for a specific MediaWiki User object
* @param User|UserIdentity|string $user
* @return string
*/
public static function createUserLinks( User|UserIdentity|string $user ): string {
global $wgMatrixMaxCharsUsernames;
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 ( $wgMatrixMaxCharsUsernames ) {
if ( strlen( $user_abbr ) > $wgMatrixMaxCharsUsernames ) {
$user_abbr = substr( $user_abbr, 0, $wgMatrixMaxCharsUsernames );
$user_abbr = $user_abbr . '...';
}
}
$userPage = self::createLink( $user_abbr, ( $isAnon ? $contribs : $user->getUserPage() )
->getFullURL( '', false, PROTO_CANONICAL ) );
$userTalk = self::createLink( wfMessage( 'matrix-talk' )->inContentLanguage()->text(),
$user->getTalkPage()->getFullURL( '', false, PROTO_CANONICAL ) );
$userContribs = self::createLink( wfMessage( 'matrix-contribs' )->inContentLanguage()->text(),
$contribs->getFullURL( '', false, PROTO_CANONICAL ) );
$text = wfMessage( 'matrix-userlinks', $userPage, $userTalk, $userContribs )->inContentLanguage()->text();
} else {
// If we were given a string, handle this differently.
$text = wfMessage( 'matrix-userlinks', self::escapeHtml( (string)$user ), 'n/a', 'n/a' )
->inContentLanguage()->text();
}
return $text;
}
/**
* Creates formatted text for a specific Revision object
* @param RevisionRecord $revision
* @return string
*/
public static function createRevisionText( RevisionRecord $revision ): string {
$diff = self::createLink( wfMessage( 'matrix-diff' )->inContentLanguage()->text(),
Title::newFromLinkTarget( $revision->getPageAsLinkTarget() )->getFullURL(
[ 'diff' => 'prev', 'oldid' => $revision->getId() ], false, PROTO_CANONICAL ) );
$minor = '';
$size = '';
if ( $revision->isMinor() ) {
$minor .= wfMessage( 'matrix-minor' )->inContentLanguage()->text();
}
$parentId = $revision->getParentId();
if ( $parentId ) {
$parent = MediaWikiServices::getInstance()->getRevisionLookup()->getRevisionById( $parentId );
if ( $parent ) {
$size .= wfMessage( 'matrix-size', sprintf( "%+d", $revision->getSize() - $parent->getSize() ) )
->inContentLanguage()->text();
}
}
if ( $size == '' ) {
$size .= wfMessage( 'matrix-size', sprintf( "%d", $revision->getSize() ) )->inContentLanguage()->text();
}
return wfMessage( 'matrix-revisionlinks', $diff, $minor, $size )->inContentLanguage()->text();
}
/**
* Converts extension-generated formatting to Matrix HTML.
* @param string $text
* @return string
*/
public static function toMatrixHtml( string $text ): string {
$text = preg_replace_callback(
'/\*\*(.+?)\*\*/s',
static function ( array $matches ): string {
return '<strong>' . self::escapeHtml( $matches[1] ) . '</strong>';
},
$text
);
$text = preg_replace_callback(
'/`([^`]+)`/',
static function ( array $matches ): string {
return '<code>' . self::escapeHtml( $matches[1] ) . '</code>';
},
$text
);
$text = preg_replace_callback(
'/(?<!\*)\*([^*\n]+)\*(?!\*)/',
static function ( array $matches ): string {
return '<em>' . self::escapeHtml( $matches[1] ) . '</em>';
},
$text
);
return $text;
}
/**
* Converts extension-generated formatting to plain text.
* @param string $text
* @return string
*/
public static function toPlainText( string $text ): string {
$html = self::toMatrixHtml( $text );
$html = preg_replace_callback(
'/<a\s+href="([^"]+)">(.+?)<\/a>/s',
static function ( array $matches ): string {
$label = html_entity_decode( strip_tags( $matches[2] ), ENT_QUOTES | ENT_HTML5, 'UTF-8' );
$url = html_entity_decode( $matches[1], ENT_QUOTES | ENT_HTML5, 'UTF-8' );
return $label . ': ' . $url;
},
$html
) ?? $html;
$plain = html_entity_decode( strip_tags( $html ), ENT_QUOTES | ENT_HTML5, 'UTF-8' );
return trim( preg_replace( '/\s+/', ' ', $plain ) ?? $plain );
}
/**
* Strip bad characters from a URL
* @param string $url
* @return string
*/
public static function encodeURL( string $url ): string {
$url = str_replace( " ", "%20", $url );
$url = str_replace( "(", "%28", $url );
return str_replace( ")", "%29", $url );
}
/**
* Formats bytes to a string representing B, KB, MB, GB, TB
* @param int $bytes
* @param ?int $precision
* @return string
*/
public static function formatBytes( int $bytes, ?int $precision = 2 ): string {
$units = [ 'B', 'KB', 'MB', 'GB', 'TB' ];
$bytes = max( $bytes, 0 );
$pow = floor( ( $bytes ? log( $bytes ) : 0 ) / log( 1024 ) );
$pow = min( $pow, count( $units ) - 1 );
$bytes /= ( 1 << ( 10 * $pow ) );
return round( $bytes, $precision ) . ' ' . $units[$pow];
}
/**
* Truncate text to maximum allowed characters
* @param string $text
* @return string
*/
public static function truncateText( string $text ): string {
global $wgMatrixMaxChars;
if ( $wgMatrixMaxChars ) {
if ( strlen( $text ) > $wgMatrixMaxChars ) {
$text = substr( $text, 0, $wgMatrixMaxChars );
$text = $text . '...';
}
}
return $text;
}
/**
* Sanitise text input to remove the potential for abuse of Matrix's role pings.
* @param string $text
* @return string
*/
public static function sanitiseText( string $text ): string {
return preg_replace( '/([`@])/', '', $text );
}
/**
* @param string $text
* @return string
*/
private static function escapeHtml( string $text ): string {
return htmlspecialchars( $text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8' );
}
}
-13
View File
@@ -1,13 +0,0 @@
<?php
namespace MediaWiki\Extension\Matrix;
use MediaWiki\MediaWikiServices;
return [
'Matrix.MatrixMessageSender' => static function ( MediaWikiServices $services ): MatrixMessageSender {
return new MatrixMessageSender(
$services->getHttpRequestFactory()
);
}
];
+264
View File
@@ -0,0 +1,264 @@
<?php
use MediaWiki\MediaWikiServices;
class DiscordUtils {
/**
* Checks if criteria is met for this action to be cancelled
*/
public static function isDisabled ( $hook, $ns, $user ) {
global $wgDiscordDisabledHooks, $wgDiscordDisabledNS, $wgDiscordDisabledUsers;
if ( is_array( $wgDiscordDisabledHooks ) ) {
if ( in_array( strtolower( $hook ), array_map( 'strtolower', $wgDiscordDisabledHooks ) ) ) {
// Hook is disabled, return true
return true;
}
} else {
wfDebugLog( 'discord', 'The value of $wgDiscordDisabledHooks is not valid and therefore all hooks are enabled.' );
}
if ( is_array( $wgDiscordDisabledNS ) ) {
if ( !is_null( $ns ) ) {
$ns = (int)$ns;
if ( in_array( $ns, $wgDiscordDisabledNS ) ) {
// Namespace is disabled, return true
return true;
}
}
} else {
wfDebugLog( 'discord', 'The value of $wgDiscordDisabledNS is not valid and therefore all namespaces are enabled.' );
}
if ( is_array( $wgDiscordDisabledUsers ) ) {
if ( !is_null( $user ) ) {
if ( $user instanceof User ) {
if ( in_array( $user->getName(), $wgDiscordDisabledUsers ) ) {
// User shouldn't trigger a message, return true
return true;
}
}
}
} else {
wfDebugLog( 'discord', 'The value of $wgDiscordDisabledUsers is not valid and therefore all users can trigger messages.' );
}
return false;
}
/**
* Handles sending a webhook to Discord using cURL
*/
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
return false;
}
$urls = [];
if ( is_array( $wgDiscordWebhookURL ) ) {
$urls = array_merge($urls, $wgDiscordWebhookURL);
} else if ( is_string($wgDiscordWebhookURL) ) {
$urls[] = $wgDiscordWebhookURL;
} else {
wfDebugLog( 'discord', 'The value of $wgDiscordWebhookURL is not valid and therefore no webhooks could be sent.' );
return false;
}
// Strip whitespace to just one space
$stripped = preg_replace('/\s+/', ' ', $msg);
if ( $wgDiscordPrependTimestamp ) {
// Add timestamp
$dateString = gmdate( wfMessage( 'discord-timestampformat' )->text() );
$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",
'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);
}
} );
return true;
}
/**
* Creates a formatted markdown link based on text and given URL
*/
public static function createMarkdownLink ($text, $url) {
global $wgDiscordSuppressPreviews;
return "[" . $text . "]" . '(' . ($wgDiscordSuppressPreviews ? '<' : '') . self::encodeURL($url) . ($wgDiscordSuppressPreviews ? '>' : '') . ')';
}
/**
* 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);
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.
$text = wfMessage( 'discord-userlinks', $user, 'n/a', 'n/a' )->text();
}
return $text;
}
/**
* Creates formatted text for a specific Revision object
*/
public static function createRevisionText ($revision) {
$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();
}
$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
*/
public static function encodeURL($url) {
$url = str_replace(" ", "%20", $url);
$url = str_replace("(", "%28", $url);
$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');
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= (1 << (10 * $pow));
return round($bytes, $precision) . ' ' . $units[$pow];
}
/**
* Truncate text to maximum allowed characters
*/
public static function truncateText($text) {
global $wgDiscordMaxChars;
if ($wgDiscordMaxChars) {
if (strlen($text) > $wgDiscordMaxChars) {
$text = substr($text, 0, $wgDiscordMaxChars);
$text = $text.'...';
}
}
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;
}
}
?>