Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
52d2a46c03
|
|||
|
3afeab518f
|
|||
| f7cd64ee42 | |||
| 491ecb389f | |||
| b0f84044cf | |||
| 7162cabf1b | |||
| 9f805a3bb0 | |||
| 111559bc3a | |||
| bf55bc9bd0 | |||
| ab732ea2b2 | |||
| d81d1e6cd1 | |||
| 342cb911a1 | |||
| 23965c4b28 | |||
| 7bce8b2218 | |||
| cd41b8661d | |||
| 19cd1e778b | |||
| e5ec85956b | |||
| 9337f420cf | |||
| 91f04aa76a | |||
| ed99a8dddd | |||
| 55e4e85ecf | |||
| 46837a7493 | |||
| d18d2db7e4 | |||
| 5504d01903 | |||
| 298106ece1 | |||
| 5fcb539889 | |||
| cf837f82aa | |||
| c2f1cee62e | |||
| e9695888f4 | |||
| ae789d15a2 | |||
| a63eaf3a85 | |||
| c575f015b3 | |||
| 07e1d5b94d | |||
| 27332b8fc6 | |||
| 1313b1b318 | |||
| 1ba60e4275 | |||
| 61c91ef4c8 | |||
| 094c9943ad | |||
| 9d14b12829 | |||
| bd74a3a6d9 | |||
| 67b73e8807 | |||
| 799a5f8462 | |||
| 6fca3ad4fe | |||
| e5a0efb4c9 | |||
| a5de5c323d | |||
| 1245a68286 | |||
| e3a356c430 | |||
| 02044f2ca0 | |||
| 7b1504bc67 | |||
| c9d3370afa | |||
| 1ae6d2505d | |||
| 818134780c | |||
| 4d52fa4644 | |||
| 2ddb00328b | |||
| ffcce02ffb | |||
| 266c428f6f | |||
| 58da9dad15 | |||
| 812cb525f3 | |||
| f30ebb0ad5 | |||
| 87546624e2 |
@@ -1,71 +1,68 @@
|
||||
# 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.
|
||||
# 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.
|
||||
|
||||
Multiple webhook URLs are supported and messages will be sent to all of them.
|
||||
|
||||
**Live demo**: https://runescape.wiki (https://discord.gg/runescapewiki)
|
||||
**Live demo**: https://runescape.wiki (https://matrix.gg/runescapewiki)
|
||||
|
||||
<p align="center">
|
||||
<img src="https://i.imgur.com/tCehglJ.png" alt="Example"/>
|
||||
</p>
|
||||
|
||||
## Requirements
|
||||
- **Discord webhook URL**: This can be obtained by editing a channel on a server with the correct permissions.
|
||||
- **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 version. For example, if you are using MediaWiki 1.37, use the `REL1_36` branch.
|
||||
- We do not guarantee support for versions of MediaWiki that are considered end-of-life.
|
||||
- The `master` branch may contain changes that are only applicable to the cutting-edge alpha version of MediaWiki.
|
||||
|
||||
### Recommended
|
||||
- **cURL**: By default, this extension sends requests using cURL. If you don't have cURL, you could try setting `$wgDiscordUseFileGetContents` to `true` instead, but this is not recommended.
|
||||
- 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.
|
||||
|
||||
## Installation
|
||||
|
||||
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`
|
||||
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`
|
||||
2. Modify your `LocalSettings.php` file and add:
|
||||
|
||||
```php
|
||||
// Load the extension
|
||||
wfLoadExtension( 'Discord' );
|
||||
wfLoadExtension( 'Matrix' );
|
||||
// Set the webhook URL(s) (string or array)
|
||||
$wgDiscordWebhookURL = [ '' ];
|
||||
$wgMatrixWebhookURL = [ '' ];
|
||||
```
|
||||
|
||||
For further configuration variables, see [below](#configuration).
|
||||
|
||||
### Getting a webhook URL
|
||||
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.
|
||||
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.
|
||||
|
||||
## Configuration
|
||||
This extension can be configured using the `LocalSettings.php` file in your MediaWiki installation.
|
||||
|
||||
| Variable | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `$wgDiscordWebhookURL` | string/array | Discord webhook URLs
|
||||
| `$wgMatrixWebhookURL` | string/array | Matrix webhook URLs
|
||||
|
||||
### Optional
|
||||
These parameters aren't required for the extension to work.
|
||||
|
||||
| Variable | Type | Description | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| `$wgDiscordNoBots` | bool | Do not send notifications that are triggered by a [bot account](https://www.mediawiki.org/wiki/Manual:Bots) | `true`
|
||||
| `$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)
|
||||
| `$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)
|
||||
|
||||
## Hooks used
|
||||
- `PageSaveComplete` - New edits to pages and page creations
|
||||
- `PageDeleteComplete` - Page deletions
|
||||
- `ArticleUndelete` - Page restorations
|
||||
- `PageUndeleteComplete` - Page restorations
|
||||
- `ArticleRevisionVisibilitySet` - Revision visibility changes
|
||||
- `ArticleProtectComplete` - Page protections
|
||||
- `PageMoveComplete` - Page moves
|
||||
@@ -77,7 +74,8 @@ 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 was merged
|
||||
- `ArticleMergeComplete` - Article histories were merged
|
||||
- `RenameUserComplete` - Rename was completed
|
||||
|
||||
### [Approved Revs](https://www.mediawiki.org/wiki/Extension:Approved_Revs)
|
||||
- `ApprovedRevsRevisionApproved` - Revision was approved
|
||||
@@ -85,13 +83,15 @@ These parameters aren't required for the extension to work.
|
||||
- `ApprovedRevsFileRevisionApproved` - File revision was approved
|
||||
- `ApprovedRevsFileRevisionUnapproved` - File revision was unapproved
|
||||
|
||||
### [Renameuser](https://www.mediawiki.org/wiki/Extension:Renameuser)
|
||||
- `RenameUserComplete` - Rename was completed
|
||||
## 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-discord).
|
||||
You can submit translations for this extension on [Translatewiki.net](https://translatewiki.net/wiki/Special:Translate/mwgithub-mw-matrix).
|
||||
|
||||
## 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-discord](https://github.com/Szmyk/mediawiki-discord) project.
|
||||
This extension was inspired by Szmyk's [mediawiki-matrix](https://github.com/Szmyk/mediawiki-matrix) project.
|
||||
|
||||
+60
-46
@@ -1,34 +1,38 @@
|
||||
{
|
||||
"name": "Discord",
|
||||
"name": "Matrix",
|
||||
"author": [
|
||||
"[https://github.com/jayktaylor Jayden Bailey]"
|
||||
"[https://github.com/jayktaylor Jayden Bailey]",
|
||||
"[https://git.pvv.ntnu.no/Projects Programvareverkstedet]"
|
||||
],
|
||||
"url": "https://github.com/jayktaylor/mw-discord",
|
||||
"version": "1.0.13",
|
||||
"descriptionmsg": "discord-desc",
|
||||
"url": "https://git.pvv.ntnu.no/Projects/mediawiki-matrix-notifs",
|
||||
"version": "1.2",
|
||||
"descriptionmsg": "matrix-desc",
|
||||
"license-name": "MIT",
|
||||
"requires": {
|
||||
"MediaWiki": ">= 1.38.0"
|
||||
"MediaWiki": ">= 1.40.0"
|
||||
},
|
||||
"manifest_version": 1,
|
||||
"config": {
|
||||
"DiscordWebhookURL": [],
|
||||
"DiscordNoBots": true,
|
||||
"DiscordNoMinor": false,
|
||||
"DiscordNoNull": true,
|
||||
"DiscordSuppressPreviews": true,
|
||||
"DiscordMaxChars": null,
|
||||
"DiscordMaxCharsUsernames": 25,
|
||||
"DiscordDisabledHooks": [],
|
||||
"DiscordDisabledNS": [],
|
||||
"DiscordDisabledUsers": [],
|
||||
"DiscordPrependTimestamp": false,
|
||||
"DiscordUseFileGetContents": false,
|
||||
"DiscordUseEmojis": false,
|
||||
"DiscordEmojis": {
|
||||
"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:",
|
||||
"ArticleUndelete": ":wastebasket:",
|
||||
"PageUndeleteComplete": ":wastebasket:",
|
||||
"ArticleRevisionVisibilitySet": ":spy:",
|
||||
"ArticleProtectComplete": ":lock:",
|
||||
"PageMoveComplete": ":truck:",
|
||||
@@ -48,33 +52,43 @@
|
||||
"RenameUserComplete": ":people_holding_hands:"
|
||||
}
|
||||
},
|
||||
"AutoloadClasses": {
|
||||
"DiscordHooks": "src/DiscordHooks.php",
|
||||
"DiscordUtils": "src/Utils.php"
|
||||
"AutoloadNamespaces": {
|
||||
"MediaWiki\\Extension\\Matrix\\": "src/"
|
||||
},
|
||||
"MessagesDirs": {
|
||||
"mw-discord": "i18n"
|
||||
"mw-matrix": "i18n"
|
||||
},
|
||||
"HookHandlers": {
|
||||
"main": {
|
||||
"class": "MediaWiki\\Extension\\Matrix\\MatrixHooks",
|
||||
"services": [
|
||||
"Matrix.MatrixMessageSender"
|
||||
]
|
||||
}
|
||||
},
|
||||
"Hooks": {
|
||||
"PageSaveComplete": "DiscordHooks::onPageSaveComplete",
|
||||
"PageDeleteComplete": "DiscordHooks::onPageDeleteComplete",
|
||||
"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"
|
||||
}
|
||||
"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"
|
||||
]
|
||||
}
|
||||
|
||||
+33
-31
@@ -1,37 +1,39 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Asma"
|
||||
"Asma",
|
||||
"Meno25",
|
||||
"Mohammed Qays"
|
||||
]
|
||||
},
|
||||
"discord-desc": "يرسل رسائل إلى قناة Discord عند وقوع أحداث معينة",
|
||||
"discord-talk": "ت",
|
||||
"discord-contribs": "ج",
|
||||
"discord-diff": "فرق",
|
||||
"discord-minor": "(م)",
|
||||
"discord-edit": "قام $1 بإنشاء $2 $3 $4",
|
||||
"discord-create": "قام $1 بإنشاء $2 $3 $4",
|
||||
"discord-articledelete": "تم حذف $1 $2 $3 (تم حذف $4 من المراجعات)",
|
||||
"discord-undeleterev": "المراجعات لـ",
|
||||
"discord-articleundelete": "$1 قام بإلغاء حذف $2 $3 $4",
|
||||
"discord-revvisibility": "$1 غيرت رؤية $2 من المراجعات على $3",
|
||||
"discord-articleprotect": "$1 تم تغييره لحماية $2 $3 ( $4 )",
|
||||
"discord-titlemove": "قام $1 بنقل من $2 إلى $3 $4 $5",
|
||||
"discord-localusercreated": "تم تسجيل $1",
|
||||
"discord-blocktimeformat": "d F Y H:i",
|
||||
"discord-blockipcomplete": "$1 حظر $2 $3 ($4)",
|
||||
"discord-unblockusercomplete": "$1 قام بإلغاء حظر $2",
|
||||
"discord-usergroupschanged": "$1 غير حقوق $2 $3 ($4) ($5)",
|
||||
"discord-uploadnewver": "إصدار جديد من",
|
||||
"discord-uploadcomplete": "قام $1 بتحميل $2 $3 $4 ($5، $6×$7 ،$8)",
|
||||
"discord-filedeletecomplete": "قام $1 بحذف نسخة من الملف $2 $3",
|
||||
"discord-fileundeletecomplete": "استعاد $1 بعض إصدارات الملف $2 $3",
|
||||
"discord-afterimportpage": "قام $1 باستيراد $2 (تم استيراد مراجعات $4 / $3)",
|
||||
"discord-timestampformat": "**H:i e:**",
|
||||
"discord-articlemergecomplete": "دمج $1 المراجعات من $2 إلى $3",
|
||||
"discord-approvedrevsrevisionapproved": "وافق $1 على مراجعة جديدة بقيمة $2 (المراجعة $3) من المستخدم $4",
|
||||
"discord-approvedrevsrevisionunapproved": "لم يوافق $1 على مراجعة الملف المعتمدة لـ $2",
|
||||
"discord-approvedrevsfilerevisionapproved": "وافق $1 على مراجعة ملف جديد بقيمة $2 ($3) من المستخدم $4",
|
||||
"discord-approvedrevsfilerevisionunapproved": "لم يوافق $1 على مراجعة الملف المعتمدة لـ $2",
|
||||
"discord-renameusercomplete": "أعاد $1 تسمية المستخدم $2 إلى $3"
|
||||
"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"
|
||||
}
|
||||
|
||||
+8
-8
@@ -4,12 +4,12 @@
|
||||
"আফতাবুজ্জামান"
|
||||
]
|
||||
},
|
||||
"discord-talk": "আ",
|
||||
"discord-contribs": "অ",
|
||||
"discord-diff": "পার্থক্য",
|
||||
"discord-minor": "(অ)",
|
||||
"discord-edit": "$1 $2 সম্পাদনা করেছেন $3 $4",
|
||||
"discord-create": "$1 $2 তৈরি করেছেন $3 $4",
|
||||
"discord-localusercreated": "$1 নিবন্ধিত হয়েছে",
|
||||
"discord-blockipcomplete": "$1 $2-কে বাধা দিয়েছেন $3 ($4)"
|
||||
"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)"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
+26
-30
@@ -6,34 +6,30 @@
|
||||
"Spyridon Eftychios Kokotos"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Στέλνει μηνύματα σε ένα κανάλι Discord όταν συμβαίνουν ορισμένα συμβάντα",
|
||||
"discord-talk": "t",
|
||||
"discord-contribs": "c",
|
||||
"discord-diff": "διαφορά",
|
||||
"discord-minor": "(μ)",
|
||||
"discord-edit": "$1 επεξεργάστηκε $2 $3 $4.",
|
||||
"discord-create": "$1 δημιούργησε $2 $3 $4",
|
||||
"discord-articledelete": "$1 διαγράφηκε $2 $3 ($4 αναθεωρήσεις διαγράφηκαν)",
|
||||
"discord-undeleterev": "αναθεωρήσεις για",
|
||||
"discord-articleundelete": "$1 επανέφερε $2 $3 $4",
|
||||
"discord-revvisibility": "$1 άλλαξε την ορατότητα των $2 αναθεωρήσεων στο $3",
|
||||
"discord-articleprotect": "$1 άλλαξε προστασία του $2 $3 ($4)",
|
||||
"discord-titlemove": "$1 μετακίνησε $2 στα $3 $4 $5",
|
||||
"discord-localusercreated": "$1 εγγεγραμμένος",
|
||||
"discord-blocktimeformat": "d F Y H:i",
|
||||
"discord-blockipcomplete": "$1 αποκλεισμένο $2 $3 ($4)",
|
||||
"discord-unblockusercomplete": "$1 ξεμπλόκαρε $2",
|
||||
"discord-usergroupschanged": "$1 άλλαξε τα δικαιώματα των $2 $3 ($4) ($5)",
|
||||
"discord-uploadnewver": "νέα έκδοση του",
|
||||
"discord-uploadcomplete": "$1 μεταφορτώθηκε $2 $3 $4 ( $5 , $6 x $7 , $8 )",
|
||||
"discord-filedeletecomplete": "$1 διέγραψε μια έκδοση του αρχείου $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 επανέφερε ορισμένες εκδόσεις του αρχείου $2 $3",
|
||||
"discord-afterimportpage": "$1 εισήχθη $2 (εισαγμένες $4 / $3 αναθεωρήσεις)",
|
||||
"discord-timestampformat": "**H:i e:**",
|
||||
"discord-articlemergecomplete": "$1 συγχώνευσε αναθεωρήσεις από $2 σε $3",
|
||||
"discord-approvedrevsrevisionapproved": "$1 ενέκρινε μια νέα αναθεώρηση των $2 (αναθεώρηση $3 ) από τον χρήστη $4",
|
||||
"discord-approvedrevsrevisionunapproved": "$1 κατάργησε την έγκριση της εγκεκριμένης αναθεώρησης του αρχείου για $2",
|
||||
"discord-approvedrevsfilerevisionapproved": "$1 ενέκρινε μια νέα αναθεώρηση αρχείου $2 ( $3 ) από τον χρήστη $4",
|
||||
"discord-approvedrevsfilerevisionunapproved": "$1 κατάργησε την έγκριση της εγκεκριμένης αναθεώρησης του αρχείου για $2",
|
||||
"discord-renameusercomplete": "$1 μετονόμασε τον χρήστη $2 σε $3"
|
||||
"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"
|
||||
}
|
||||
|
||||
+34
-33
@@ -4,37 +4,38 @@
|
||||
"Jayden Bailey"
|
||||
]
|
||||
},
|
||||
"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"
|
||||
"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"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
+29
-33
@@ -1,40 +1,36 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Gomoko",
|
||||
"Verdy p"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Envoie des messages à un canal Discord quand certains événements surviennent",
|
||||
"discord-userlinks": "$1 ($2|$3)",
|
||||
"discord-revisionlinks": "($1) $2 $3",
|
||||
"discord-talk": "t",
|
||||
"discord-contribs": "c",
|
||||
"discord-diff": "diff",
|
||||
"discord-minor": "(m)",
|
||||
"discord-size": "($1)",
|
||||
"discord-edit": "$1 a modifié $2 $3 : $4",
|
||||
"discord-create": "$1 a créé $2 $3 : $4",
|
||||
"discord-articledelete": "$1 a supprimé $2 ($4 version(s) supprimée(s)) : $3",
|
||||
"discord-undeleterev": "versions pour",
|
||||
"discord-articleundelete": "$1 a restauré $2 $3 : $4",
|
||||
"discord-revvisibility": "$1 a modifié la visibilité de $2 version(s) sur $3",
|
||||
"discord-articleprotect": "$1 a modifié la protection de $2 ($4) : $3",
|
||||
"discord-titlemove": "$1 a renommé $2 en $3 $5 : $4",
|
||||
"discord-localusercreated": "$1 s’est inscrit(e)",
|
||||
"discord-blocktimeformat": "d F Y H:i",
|
||||
"discord-blockipcomplete": "$1 a bloqué $2 ($4) : $3",
|
||||
"discord-unblockusercomplete": "$1 a débloqué $2",
|
||||
"discord-usergroupschanged": "$1 a modifié les droits de $2 ($4) ($5) : $3",
|
||||
"discord-uploadnewver": "nouvelle version de",
|
||||
"discord-uploadcomplete": "$1 a téléversé $2 $3 ($5, $6x$7, $8) : $4",
|
||||
"discord-filedeletecomplete": "$1 a supprimé une version du fichier $2 : $3",
|
||||
"discord-fileundeletecomplete": "$1 a restauré certaines versions du fichier $2 : $3",
|
||||
"discord-afterimportpage": "$1 a importé $2 ($4 / $3 révisions importées)",
|
||||
"discord-timestampformat": "**H:i e:**",
|
||||
"discord-articlemergecomplete": "$1 a fusionné des versions de $2 vers $3",
|
||||
"discord-approvedrevsrevisionapproved": "$1 a approuvé une nouvelle version de $2 (version $3) créée par $4",
|
||||
"discord-approvedrevsrevisionunapproved": "$1 a désapprouvé la version approuvée de $2",
|
||||
"discord-approvedrevsfilerevisionapproved": "$1 a approuvé une nouvelle version de fichier dans $2 ($3) créée par $4",
|
||||
"discord-approvedrevsfilerevisionunapproved": "$1 a désapprouvé la version de fichier approuvée dans $2",
|
||||
"discord-renameusercomplete": "$1 a renommé l’utilisateur ou l’utilisatrice $2 en $3"
|
||||
"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 s’est 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é l’utilisateur ou l’utilisatrice $2 en $3"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
+30
-30
@@ -4,34 +4,34 @@
|
||||
"McDutchie"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Invia messages a un canal Discord quando certe eventos occurre",
|
||||
"discord-talk": "t",
|
||||
"discord-contribs": "c",
|
||||
"discord-diff": "diff",
|
||||
"discord-minor": "(m)",
|
||||
"discord-edit": "$1 ha modificate $2 $3 $4",
|
||||
"discord-create": "$1 ha create $2 $3 $4",
|
||||
"discord-articledelete": "$1 ha delite $2 $3 ($4 versiones delite)",
|
||||
"discord-undeleterev": "versiones pro",
|
||||
"discord-articleundelete": "$1 ha restaurate $2 $3 $4",
|
||||
"discord-revvisibility": "$1 ha cambiate le visibilitate de of $2 versiones sur $3",
|
||||
"discord-articleprotect": "$1 ha cambiate le protection de $2 $3 ($4)",
|
||||
"discord-titlemove": "$1 ha renominate $2 a $3 $4 $5",
|
||||
"discord-localusercreated": "$1 se ha inscribite",
|
||||
"discord-blocktimeformat": "d F Y H:i",
|
||||
"discord-blockipcomplete": "$1 ha blocate $2 $3 ($4)",
|
||||
"discord-unblockusercomplete": "$1 ha disblocate $2",
|
||||
"discord-usergroupschanged": "$1 ha cambiate le derectos de $2 $3 ($4) ($5)",
|
||||
"discord-uploadnewver": "nove version de",
|
||||
"discord-uploadcomplete": "$1 ha incargate $2 $3 $4 ($5, $6x$7, $8)",
|
||||
"discord-filedeletecomplete": "$1 ha delite un version del file $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 ha restaurate alcun versiones del file $2 $3",
|
||||
"discord-afterimportpage": "$1 ha importate $2 ($4/$3 versiones importate)",
|
||||
"discord-timestampformat": "**H:i e:**",
|
||||
"discord-articlemergecomplete": "$1 ha fusionate le versiones de $2 in $3",
|
||||
"discord-approvedrevsrevisionapproved": "$1 ha approbate un nove version de $2 (version $3) del usator $4",
|
||||
"discord-approvedrevsrevisionunapproved": "$1 ha disapprobate le version approbate de $2",
|
||||
"discord-approvedrevsfilerevisionapproved": "$1 ha approbate un nove version del file $2 ($3) del usator $4",
|
||||
"discord-approvedrevsfilerevisionunapproved": "$1 ha disapprobate le version approbate del file $2",
|
||||
"discord-renameusercomplete": "$1 ha renominate le usator $2 a $3"
|
||||
"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"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"@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님으로 변경함"
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
+31
-30
@@ -4,34 +4,35 @@
|
||||
"Bjankuloski06"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Испраќа пораки на канал на Дискорд кога ќе се случат извесни настани",
|
||||
"discord-talk": "t",
|
||||
"discord-contribs": "c",
|
||||
"discord-diff": "разл",
|
||||
"discord-minor": "(м)",
|
||||
"discord-edit": "$1 уреди $2 $3 $4",
|
||||
"discord-create": "$1 создаде $2 $3 $4",
|
||||
"discord-articledelete": "$1 избриша $2 $3 (избришани $4 преработки)",
|
||||
"discord-undeleterev": "преработки за",
|
||||
"discord-articleundelete": "$1 поврати $2 $3 $4",
|
||||
"discord-revvisibility": "$1 смени видливост на $2 преработки на $3",
|
||||
"discord-articleprotect": "$1 смени заштита на $2 $3 ($4)",
|
||||
"discord-titlemove": "$1 премести $2 на $3 $4 $5",
|
||||
"discord-localusercreated": "$1 зачленети",
|
||||
"discord-blocktimeformat": "j F Y G:i ч.",
|
||||
"discord-blockipcomplete": "$1 блокираше $2 $3 ($4)",
|
||||
"discord-unblockusercomplete": "$1 одблокираше $2",
|
||||
"discord-usergroupschanged": "$1 ги смени правата на $2 $3 ($4) ($5)",
|
||||
"discord-uploadnewver": "нова преработка на",
|
||||
"discord-uploadcomplete": "$1 подигна $2 $3 $4 ($5, $6×$7, $8)",
|
||||
"discord-filedeletecomplete": "$1 избриша верзија на податотека $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 поврати некои верзии на податотека $2 $3",
|
||||
"discord-afterimportpage": "$1 увезе $2 (увезени $4/$3 преработки)",
|
||||
"discord-timestampformat": "**G:i ч. e:**",
|
||||
"discord-articlemergecomplete": "$1 спои преработки од $2 во $3",
|
||||
"discord-approvedrevsrevisionapproved": "$1 одобри нова преработка на $2 (преработка $3) од корисникот $4",
|
||||
"discord-approvedrevsrevisionunapproved": "$1 тргна одобрение од одобрената преработка за $2",
|
||||
"discord-approvedrevsfilerevisionapproved": "$1 одобри нова преработка на податотека на $2 ($3) од корисникот $4",
|
||||
"discord-approvedrevsfilerevisionunapproved": "$1 тргна одобрение од одобрената преработка на податотека за $2",
|
||||
"discord-renameusercomplete": "$1 го преименуваше корисникот $2 во $3"
|
||||
"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"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
+19
-24
@@ -4,28 +4,23 @@
|
||||
"Railfail536"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Wysyła wiadomości o dokonywanych akcjach na serwer Discord",
|
||||
"discord-userlinks": "$1 ($2|$3)",
|
||||
"discord-revisionlinks": "($1) $2 $3",
|
||||
"discord-talk": "d",
|
||||
"discord-contribs": "w",
|
||||
"discord-diff": "różn.",
|
||||
"discord-minor": "(m)",
|
||||
"discord-size": "($1)",
|
||||
"discord-edit": "$1 edytował $2 $3 $4",
|
||||
"discord-articledelete": "$1 usunął $2 $3 ($4 wersje usunięte)",
|
||||
"discord-undeleterev": "wersje",
|
||||
"discord-articleundelete": "$1 odtworzył $2 $3 $4",
|
||||
"discord-revvisibility": "$1 zmienił widoczność $2 wersji $3",
|
||||
"discord-articleprotect": "$1 zmienił poziom zabezpoeczenia strony $2 $2 $3 ($4)",
|
||||
"discord-titlemove": "$1 przeniósł $2 na $3 $4 $5",
|
||||
"discord-localusercreated": "$1 założył konto",
|
||||
"discord-blocktimeformat": "d F Y H:i",
|
||||
"discord-blockipcomplete": "$1 zablokował $2 $3 ($4)",
|
||||
"discord-unblockusercomplete": "$1 zdjął blokadę z $2",
|
||||
"discord-usergroupschanged": "$1 zmienił uprawnienia użytkownika $2 $3 ($4) ($5)",
|
||||
"discord-uploadnewver": "nową wersję",
|
||||
"discord-uploadcomplete": "$1 przesłał $2 $3 $4 ($5, $6x$7, $8)",
|
||||
"discord-filedeletecomplete": "$1 usunął wersję pliku $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 odtworzył wersje pliku $2 $3"
|
||||
"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"
|
||||
}
|
||||
|
||||
+36
-34
@@ -4,40 +4,42 @@
|
||||
"Abijeet Patro",
|
||||
"Amire80",
|
||||
"Jayden",
|
||||
"Jayden Bailey"
|
||||
"Jayden Bailey",
|
||||
"McDutchie"
|
||||
]
|
||||
},
|
||||
"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 - {{msg-mw|discord-talk}}\n* $3 - {{msg-mw|discord-contribs}}",
|
||||
"discord-revisionlinks": "Used for display of revision links. Parameters\n* $1 - {{msg-mw|discord-diff}}\n* $2 - {{msg-mw|discord-minor}}\n* $3 - {{msg-mw|discord-size}}",
|
||||
"discord-talk": "Short for \"talk\".\n\nUsed as the text for $2 in {{msg-mw|discord-userlinks}}",
|
||||
"discord-contribs": "Short for \"contributions\".\n\nUsed as the text for $3 in {{msg-mw|discord-userlinks}}",
|
||||
"discord-diff": "Used as the text for $1 in discord-revisionlinks",
|
||||
"discord-minor": "Used as the text for $2 in {{msg-mw|discord-revisionlinks}}",
|
||||
"discord-size": "{{Optional}}\nUsed 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.\nParameters:\n* $1 - discord-userlinks\n* $2 - discord-undeleterev\n* $3 - Page link\n* $4 - Comment (always surrounded in tildes)",
|
||||
"discord-revvisibility": "Message sent to Discord when the visibility of revisions is changed.\nParameters:\n* $1 - discord-userlinks\n* $2 - Number of revisions\n* $3 - Page link",
|
||||
"discord-articleprotect": "Message sent to Discord when an article's protection is changed.\nParameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - Reason (always surrounded in tildes)\n* $4 - Protection settings",
|
||||
"discord-titlemove": "Message sent to Discord when an article is moved. Parameters:\n* $1 - discord-userlinks\n* $2 - Old page link\n* $3 - New page link\n* $4 - Reason (always surrounded in tildes)\n* $5 - discord-revisionlinks",
|
||||
"discord-localusercreated": "Message sent to Discord when a user registers.\nParameters:\n* $1 - discord-userlinks",
|
||||
"discord-blocktimeformat": "The formatting used in the date() function for displaying the time a user is blocked for.\n\nSee also: https://www.php.net/manual/en/datetime.format.php",
|
||||
"discord-blockipcomplete": "Message sent to Discord when a user is blocked. Parameters:\n* $1 - discord-userlinks (performer)\n* $2 - discord-userlinks (target)\n* $3 - Reason (always surrounded in tildes)\n* $4 - Expiry text (using discord-blocktimeformat)",
|
||||
"discord-unblockusercomplete": "Message sent to Discord when a user is unblocked. Parameters:\n$1 - discord-userlinks (performer)\n$2 - discord-userlinks (target)",
|
||||
"discord-usergroupschanged": "Message sent to Discord when a user's group is changed. Parameters:\n* $1 - discord-userlinks (performer)\n* $2 - discord-userlinks (target)\n* $3 - Reason (always surrounded in tildes)\n* $4 - Added rights (prepended by +)\n* $5 - Removed rights (prepended by -)",
|
||||
"discord-uploadnewver": "Used as the text for $2 in discord-uploadcomplete",
|
||||
"discord-uploadcomplete": "Message sent to Discord when an upload is made. Parameters:\n\n* $1 - discord-userlinks\n* $2 - discord-uploadnewver\n* $3 - File link\n* $4 - Comment (always surrounded in tildes)\n* $5 - Size (formatted as KB/MB/GB)\n* $6 - File width\n* $7 - File height\n* $8 - File MIME type",
|
||||
"discord-filedeletecomplete": "Message sent to Discord when a file version is deleted (not an entire file).\nParameters:\n* $1 - discord-userlinks\n* $2 - File link\n* $3 - Comment (always surrounded in tildes)",
|
||||
"discord-fileundeletecomplete": "Message sent to Discord when a file version is restored (not an entire file).\nParameters:\n* $1 - discord-userlinks\n* $2 - File link\n* $3 - Comment (always surrounded in tildes)",
|
||||
"discord-afterimportpage": "Message sent to Discord when a page is imported. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - Number of revisions in XML file\n* $4 - Number of revisions successfully imported",
|
||||
"discord-timestampformat": "The formatting used in the gmdate() function for displaying the time an event happened in UTC.\n\nSee also: https://www.php.net/manual/en/datetime.format.php",
|
||||
"discord-articlemergecomplete": "Message sent to Discord when page histories are merged. Parameters:\n* $1 - discord-userlinks\n* $2 - Target link\n* $3 - Destination link",
|
||||
"discord-approvedrevsrevisionapproved": "Message sent to Discord when a revision is approved (Approved Revs extension).\nParameters:\n* $1 - discord-userlinks (admin user)\n* $2 - Target link\n* $3 - Revision link or ID\n* $4 - discord-userlinks (revision author) or ID",
|
||||
"discord-approvedrevsrevisionunapproved": "Message sent to Discord when a revision is unapproved (Approved Revs extension).\nParameters:\n* $1 - discord-userlinks (admin user)\n* $2 - Target link",
|
||||
"discord-approvedrevsfilerevisionapproved": "Message sent to Discord when a file revision is approved (Approved Revs extension).\nParameters:\n* $1 - discord-userlinks (admin user)\n* $2 - Target link\n* $3 - SHA of uploaded file\n* $4 - discord-userlinks (revision author)",
|
||||
"discord-approvedrevsfilerevisionunapproved": "Message sent to Discord when a file revision is unapproved (Approved Revs extension).\nParameters:\n* $1 - discord-userlinks (admin user)\n* $2 - Target link",
|
||||
"discord-renameusercomplete": "Message sent to Discord when a user is renamed (Renameuser extension).\nParameters:\n* $1 - discord-userlinks (admin user)\n* $2 - Old username\n* $3 - New username link"
|
||||
"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"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
+31
-31
@@ -1,37 +1,37 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Eleassar"
|
||||
"Eleassar",
|
||||
"Upwinxp"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Pošlje sporočila na kanal Discord ob nekaterih dogodkih",
|
||||
"discord-talk": "t",
|
||||
"discord-contribs": "c",
|
||||
"discord-diff": "razl",
|
||||
"discord-minor": "(m)",
|
||||
"discord-edit": "$1 je uredil_a $2 $3 $4",
|
||||
"discord-create": "$1 je ustvaril_a $2 $3 $4",
|
||||
"discord-articledelete": "$1 je izbrisal_a $2 $3 (izbrisanih $4 redakcij)",
|
||||
"discord-undeleterev": "redakcije za",
|
||||
"discord-articleundelete": "$1 je odizbrisal_a $2 $3 $4",
|
||||
"discord-revvisibility": "$1 je spremenil_a vidnost $2 redakcij strani $3",
|
||||
"discord-articleprotect": "$1 je spremenil_a zaščito $2 $3 ($4)",
|
||||
"discord-titlemove": "$1 je prestavil_a $2 na $3 $4 $5",
|
||||
"discord-localusercreated": "Registracija $1",
|
||||
"discord-blocktimeformat": "d. F Y, H:i",
|
||||
"discord-blockipcomplete": "$1 je blokiral_a $2 $3 ($4)",
|
||||
"discord-unblockusercomplete": "$1 je odblokiral_a $2",
|
||||
"discord-usergroupschanged": "$1 je spremenil_a pravice $2 $3 ($4) ($5)",
|
||||
"discord-uploadnewver": "nova različica datoteke",
|
||||
"discord-uploadcomplete": "$1 je naložil_a $2 $3 $4 ($5, $6 × $7, $8)",
|
||||
"discord-filedeletecomplete": "$1 je izbrisal_a različico datoteke $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 je obnovil_a nekaj različic datoteke $2 $3",
|
||||
"discord-afterimportpage": "$1 je uvozil_a $2 (uvoženih $4/$3 redakcij)",
|
||||
"discord-timestampformat": "**H:i e:**",
|
||||
"discord-articlemergecomplete": "$1 je združil_a redakcije iz $2 v $3",
|
||||
"discord-approvedrevsrevisionapproved": "$1 je odobril_a novo redakcijo $2 (redakcija $3) uporabnika_ce $4",
|
||||
"discord-approvedrevsrevisionunapproved": "$1 je od-odobrila odobreno redakcijo za $2",
|
||||
"discord-approvedrevsfilerevisionapproved": "$1 je odobril_a novo različico datoteke $2 ($3) uporabnika_ce $4",
|
||||
"discord-approvedrevsfilerevisionunapproved": "$1 je od-odobrila odobreno redakcijo datoteke za $2",
|
||||
"discord-renameusercomplete": "$1 je preimenoval_a uporabnika $2 v $3"
|
||||
"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 × $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"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
+29
-9
@@ -1,16 +1,36 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"KockaAdmiralac",
|
||||
"Milicevic01"
|
||||
]
|
||||
},
|
||||
"discord-talk": "р",
|
||||
"discord-contribs": "д",
|
||||
"discord-diff": "разл",
|
||||
"discord-minor": "(м)",
|
||||
"discord-create": "$1 ја направио $2 $3 $4",
|
||||
"discord-localusercreated": "$1 се регистровао",
|
||||
"discord-blockipcomplete": "$1 је блокирао $2 $3 ($4)",
|
||||
"discord-afterimportpage": "$1 је увезао $2 (увезено $4/$3 ревизија)",
|
||||
"discord-renameusercomplete": "$1 је преименовао корисника $2 у $3"
|
||||
"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"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
+30
-26
@@ -1,32 +1,36 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Sabelöga"
|
||||
"Sabelöga",
|
||||
"Stefan2255"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Skickar meddelanden till en Discord-kanal när vissa händelser sker",
|
||||
"discord-diff": "skillnad",
|
||||
"discord-edit": "$1 redigerade $2 $3 $4",
|
||||
"discord-create": "$1 skapade $2 $3 $4",
|
||||
"discord-articledelete": "$1 raderade $2 $3 ( $4 sidvisioner raderade)",
|
||||
"discord-undeleterev": "sidversioner för",
|
||||
"discord-articleundelete": "$1 återställde $2 $3 $4",
|
||||
"discord-revvisibility": "$1 ändrade synligheten för $2 sidversioner på $3",
|
||||
"discord-articleprotect": "$1 ändrade skrivskydd av $2 $3 ($4)",
|
||||
"discord-titlemove": "$1 flyttade $2 till $3 $4 $5",
|
||||
"discord-localusercreated": "$1 registrerade",
|
||||
"discord-blockipcomplete": "$1 blockerade $2 $3 ($4)",
|
||||
"discord-unblockusercomplete": "$1 avblockerade $2",
|
||||
"discord-usergroupschanged": "$1 ändrade rättigheter för $2 $3 ($4) ($5)",
|
||||
"discord-uploadnewver": "ny version av",
|
||||
"discord-uploadcomplete": "$1 laddade upp $2 $3 $4 ($5, $6x$7, $8)",
|
||||
"discord-filedeletecomplete": "$1 raderad en version av filen $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 återställde några versioner av filen $2 $3",
|
||||
"discord-afterimportpage": "$1 importerade $2 (importerade $4/$3 sidversioner)",
|
||||
"discord-articlemergecomplete": "$1 sammanfogade sidversioner från $2 till $3",
|
||||
"discord-approvedrevsrevisionapproved": "$1 godkände en ny sidversion av $2 (sidversion $3) från användare $4",
|
||||
"discord-approvedrevsrevisionunapproved": "$1 drog in godkännandet av sidversionen för $2",
|
||||
"discord-approvedrevsfilerevisionapproved": "$1 godkände en ny filrevision av $2 ($3) från användare $4",
|
||||
"discord-approvedrevsfilerevisionunapproved": "$1 drog in godkännandet för filrevisionen för $2",
|
||||
"discord-renameusercomplete": "$1 bytte namn på användare $2 till $3"
|
||||
"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"
|
||||
}
|
||||
|
||||
+14
-14
@@ -4,18 +4,18 @@
|
||||
"Tbodt"
|
||||
]
|
||||
},
|
||||
"discord-talk": "tk",
|
||||
"discord-contribs": "pl",
|
||||
"discord-diff": "ante",
|
||||
"discord-minor": "(lili)",
|
||||
"discord-edit": "$1 li ante e lipu $2 $3 $4",
|
||||
"discord-create": "$1 li pali e lipu $2 $3 $4",
|
||||
"discord-articledelete": "$1 li weka e lipu $2 $3 (lipu li ante lon tenpo $4)",
|
||||
"discord-articleundelete": "$1 li lon sin e lipu $2 $3 $4",
|
||||
"discord-titlemove": "$1 li ante e nimi lipu $2 tawa nimi $3 $4 $5",
|
||||
"discord-localusercreated": "$1 li kama lon",
|
||||
"discord-blockipcomplete": "$1 li ken ala e $2 $3 ($4)",
|
||||
"discord-unblockusercomplete": "$1 li ken sin e $2",
|
||||
"discord-usergroupschanged": "$1 li ante e ken jan lon $2 $3 ($4) ($5)",
|
||||
"discord-renameusercomplete": "$1 li ante e nimi jan $2 tawa nimi $3"
|
||||
"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"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"@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ı"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
+30
-30
@@ -4,34 +4,34 @@
|
||||
"Kly"
|
||||
]
|
||||
},
|
||||
"discord-desc": "當某些事件發生時向 Discord 頻道發送訊息",
|
||||
"discord-talk": "t",
|
||||
"discord-contribs": "c",
|
||||
"discord-diff": "差異",
|
||||
"discord-minor": "(m)",
|
||||
"discord-edit": "$1編輯了$2、$3:$4",
|
||||
"discord-create": "$1建立了$2、$3:$4",
|
||||
"discord-articledelete": "$1刪除了$2:$3(已刪除修訂 $4)",
|
||||
"discord-undeleterev": "修訂為",
|
||||
"discord-articleundelete": "$1取消刪除$2 $3,意見:$4",
|
||||
"discord-revvisibility": "$1更改了在$3上修訂$2的可見度",
|
||||
"discord-articleprotect": "$1更改了$2的保護($4),原因:$3",
|
||||
"discord-titlemove": "$1將$2移動到$3,原因:$4,修訂連結:$5",
|
||||
"discord-localusercreated": "$1已註冊",
|
||||
"discord-blocktimeformat": "d F Y H:i",
|
||||
"discord-blockipcomplete": "$1封鎖了$2,原因:$3($4)",
|
||||
"discord-unblockusercomplete": "$1取消封鎖$2",
|
||||
"discord-usergroupschanged": "$1更改了$2的權限(新增:$4)(移除:$5),原因:$3",
|
||||
"discord-uploadnewver": "新版本的",
|
||||
"discord-uploadcomplete": "$1上傳了$2 $3($5,$6x$7,$8),意見:$4",
|
||||
"discord-filedeletecomplete": "$1刪除了檔案$2的一個版本,意見:$3",
|
||||
"discord-fileundeletecomplete": "$1恢復了檔案$2的一些版本,意見:$3",
|
||||
"discord-afterimportpage": "$1匯入了$2(匯入 $4/$3 個修訂)",
|
||||
"discord-timestampformat": "**H:i e:**",
|
||||
"discord-articlemergecomplete": "$1將$2的修訂合併到$3",
|
||||
"discord-approvedrevsrevisionapproved": "$1批准了來自使用者$4的$2新修訂($3)",
|
||||
"discord-approvedrevsrevisionunapproved": "$1取消批准$2的已批准修訂",
|
||||
"discord-approvedrevsfilerevisionapproved": "$1批准了來自使用者$4的$2新檔案修訂($3)",
|
||||
"discord-approvedrevsfilerevisionunapproved": "$1取消批准$2已批准的檔案修訂",
|
||||
"discord-renameusercomplete": "$1將使用者$2重新命名為$3"
|
||||
"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"
|
||||
}
|
||||
|
||||
@@ -1,559 +0,0 @@
|
||||
<?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 = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $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/PageDeleteComplete
|
||||
*/
|
||||
public static function onPageDeleteComplete( MediaWiki\Page\ProperPageIdentity $page, MediaWiki\Permissions\Authority $deleter, string $reason, int $pageID, MediaWiki\Revision\RevisionRecord $deletedRev, ManualLogEntry $logEntry, int $archivedRevisionCount ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'ArticleDeleteComplete';
|
||||
|
||||
$user = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity($deleter->getUser());
|
||||
$page = MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle($page);
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, $page->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( $page->getTitle(), $page->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 = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $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;
|
||||
}
|
||||
|
||||
$target = $block->getTargetUserIdentity();
|
||||
if ( $target === null ) {
|
||||
$target = $block->getTargetName();
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-blockipcomplete', DiscordUtils::createUserLinks( $user ), DiscordUtils::createUserLinks( $target ),
|
||||
( $block->getReasonComment()->text ? ('`' . DiscordUtils::sanitiseText( DiscordUtils::truncateText( $block->getReasonComment()->text ) ) . '`' ) : '' ),
|
||||
$expiryMsg )->plain();
|
||||
DiscordUtils::handleDiscord($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;
|
||||
}
|
||||
|
||||
$target = $block->getTargetUserIdentity();
|
||||
if ( $target === null ) {
|
||||
$target = $block->getTargetName();
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-unblockusercomplete', DiscordUtils::createUserLinks( $user ), DiscordUtils::createUserLinks( $target ) )->text();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $lf->getUploader() );
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, NS_FILE, $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot change
|
||||
return true;
|
||||
}
|
||||
|
||||
$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 = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity( $displayedFile->getUploader() );
|
||||
|
||||
$msg = wfMessage( 'discord-approvedrevsfilerevisionapproved', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ),
|
||||
DiscordUtils::createMarkdownLink( 'direct', $displayedFileUrl ),
|
||||
DiscordUtils::createUserLinks( $uploader ) )->plain();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a file is unapproved (Approved Revs extension)
|
||||
* @see https://github.com/wikimedia/mediawiki-extensions-ApprovedRevs/blob/REL1_34/includes/ApprovedRevs_body.php
|
||||
*/
|
||||
public static function onApprovedRevsFileRevisionUnapproved ( $parser, $title ) {
|
||||
global $wgDiscordNoBots;
|
||||
$hookName = 'ApprovedRevsFileRevisionUnapproved';
|
||||
|
||||
$user = RequestContext::getMain()->getUser();
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, $title->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-approvedrevsfilerevisionunapproved', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullURL( '', false, PROTO_CANONICAL ) ) )->plain();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a user is renamed (Renameuser extension)
|
||||
* @see https://github.com/wikimedia/mediawiki-extensions-Renameuser/blob/REL1_36/includes/RenameuserSQL.php
|
||||
*/
|
||||
public static function onRenameUserComplete ( $uid, $old, $new ) {
|
||||
$hookName = 'RenameUserComplete';
|
||||
|
||||
$user = RequestContext::getMain()->getUser();
|
||||
|
||||
if ( DiscordUtils::isDisabled( $hookName, null, null ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$renamedUserAsTitle = MediaWikiServices::getInstance()->getUserFactory()->newFromName( $new )->getUserPage();
|
||||
|
||||
$msg = wfMessage( 'discord-renameusercomplete', DiscordUtils::createUserLinks( $user ),
|
||||
"*$old*",
|
||||
DiscordUtils::createMarkdownLink( $new, $renamedUserAsTitle->getFullURL( '', false, PROTO_CANONICAL ) ) )->plain();
|
||||
DiscordUtils::handleDiscord($hookName, $msg);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,716 @@
|
||||
<?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 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
<?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' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace MediaWiki\Extension\Matrix;
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
return [
|
||||
'Matrix.MatrixMessageSender' => static function ( MediaWikiServices $services ): MatrixMessageSender {
|
||||
return new MatrixMessageSender(
|
||||
$services->getHttpRequestFactory()
|
||||
);
|
||||
}
|
||||
];
|
||||
-273
@@ -1,273 +0,0 @@
|
||||
<?php
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
|
||||
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 UserIdentity ) {
|
||||
$user = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity($user);
|
||||
}
|
||||
|
||||
if ( $user instanceof User ) {
|
||||
if ( in_array( $user->getName(), $wgDiscordDisabledUsers ) ) {
|
||||
// User shouldn't trigger a message, return true
|
||||
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 UserIdentity ) {
|
||||
// If we were passed a UserIdentity object, get the relevant user.
|
||||
$user = MediaWikiServices::getInstance()->getUserFactory()->newFromUserIdentity($user);
|
||||
}
|
||||
|
||||
if ( $user instanceof User ) {
|
||||
$isAnon = $user->isAnon();
|
||||
$contribs = Title::newFromText("Special:Contributions/" . $user);
|
||||
$user_abbr = strval($user);
|
||||
|
||||
if ($wgDiscordMaxCharsUsernames) {
|
||||
if (strlen($user_abbr) > $wgDiscordMaxCharsUsernames) {
|
||||
$user_abbr = substr($user_abbr, 0, $wgDiscordMaxCharsUsernames);
|
||||
$user_abbr = $user_abbr.'...';
|
||||
}
|
||||
}
|
||||
|
||||
$userPage = DiscordUtils::createMarkdownLink( $user_abbr, ( $isAnon ? $contribs : $user->getUserPage() )->getFullURL( '', false, PROTO_CANONICAL ) );
|
||||
$userTalk = DiscordUtils::createMarkdownLink( wfMessage( 'discord-talk' )->text(), $user->getTalkPage()->getFullURL( '', false, PROTO_CANONICAL ) );
|
||||
$userContribs = DiscordUtils::createMarkdownLink( wfMessage( 'discord-contribs' )->text(), $contribs->getFullURL( '', false, PROTO_CANONICAL ) );
|
||||
$text = wfMessage( 'discord-userlinks', $userPage, $userTalk, $userContribs )->text();
|
||||
} else {
|
||||
// If we were given a string, handle this differently.
|
||||
$text = wfMessage( 'discord-userlinks', $user, 'n/a', 'n/a' )->text();
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user