Compare commits

...

22 Commits

Author SHA1 Message Date
Jayden Bailey 0df5463a87 Bump extension version 2019-07-19 16:59:04 +01:00
Jayden Bailey 10b4db72f7 Link directly to contribs page when user is anonymous
Resolves #12
2019-07-19 16:58:41 +01:00
Jayden Bailey fb9ada8f9c Drop cURL timeout down to 10 seconds incase of Discord downtime 2019-07-19 16:40:20 +01:00
Jayden Bailey 9a7dd03d5c Add option for using file_get_contents
Resolves #14
2019-07-19 16:39:38 +01:00
Jayden Bailey fa9149165d Bump version and update readme 2019-06-16 13:39:56 +01:00
Jayden Bailey ca3a5f8047 Add option to include timestamps on messages
Closes #11
2019-06-16 13:38:15 +01:00
Jayden Bailey 591ef8746e Merge pull request #8 from Dinoguy1000/patch-2
consistently suppress bot actions...
2019-05-13 18:33:47 +01:00
Dinoguy1000 6c2e30deab bump version number too 2019-04-30 19:28:29 -05:00
Dinoguy1000 ce780adf10 Update DiscordHooks.php 2019-04-30 19:22:35 -05:00
Jayden Bailey 680040e823 Merge pull request #3 from Railfail536/patch-1
Add Polish i18n
2019-05-01 01:20:57 +01:00
Jayden Bailey 8fa8dce03d Merge pull request #7 from Dinoguy1000/patch-1
default to revision size for diff size
2019-05-01 01:14:21 +01:00
Dinoguy1000 c3bdbecee5 consistently suppress bot actions...
...when $wgDiscordNoBots is true. This prevents (un)deletions, (un)protections, and file uploads from being reported when performed by a bot. Also did a bit of globals cleanup in one function.
2019-04-29 15:05:53 -05:00
Dinoguy1000 6ccca7b823 default to revision size for diff size
Certain events (primarily page creations) fail to display a diff size because there effectively is no diff (there is no previous revision to diff with); in these cases, just display the size of the current revision.
2019-04-29 14:52:52 -05:00
Jayden Bailey 03d612a3f7 handle potential strings in createUserLinks 2019-04-24 11:11:00 +01:00
Jayden Bailey 9830df7e97 Merge pull request #5 from xunto/xunto-patch-2
Fix unneeded broken curl_exec (Unknown Error with Visual Editor)
2019-01-29 22:16:11 +00:00
Orlov Valentine cecb90dffc Fix unneeded broken curl_exec 2019-01-30 00:44:53 +03:00
Jayden Bailey 9034275470 Update extension.json 2019-01-29 13:33:50 +00:00
Jayden Bailey 3f1e1e784b Add different message for page creations
Closes #4
2019-01-29 13:32:40 +00:00
Rail 78d66e5e31 + pl.json 2019-01-28 12:19:52 +01:00
Jayden Bailey f0cf5a741d fix substitution on remaining hooks 2019-01-24 16:51:05 +00:00
Jayden Bailey c193c24be2 better checks for file namespace 2019-01-22 16:22:26 +00:00
Jayden Bailey 4b46212f49 stop substitution for edit summaries 2019-01-22 16:02:28 +00:00
7 changed files with 181 additions and 57 deletions
+2
View File
@@ -49,6 +49,8 @@ This extension can be configured using the `LocalSettings.php` file in your Medi
| `$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`
## Hooks used
- `PageContentSaveComplete` - New edits to pages and page creations
+4 -2
View File
@@ -4,7 +4,7 @@
"[https://github.com/jaydenkieran Jayden Bailey]"
],
"url": "https://github.com/jaydenkieran/mw-discord",
"version": "1.0.2",
"version": "1.0.7",
"descriptionmsg": "discord-desc",
"license-name": "MIT",
"manifest_version": 1,
@@ -17,7 +17,9 @@
"DiscordMaxChars": null,
"DiscordDisabledHooks": [],
"DiscordDisabledNS": [],
"DiscordDisabledUsers": []
"DiscordDisabledUsers": [],
"DiscordPrependTimestamp": false,
"DiscordUseFileGetContents": false
},
"AutoloadClasses": {
"DiscordHooks": "src/DiscordHooks.php",
+8 -1
View File
@@ -1,4 +1,9 @@
{
"@metadata": {
"authors": [
"Jayden Bailey"
]
},
"discord-desc": "Sends messages to a Discord channel when certain events occur",
"discord-userlinks": "$1 ($2|$3)",
"discord-revisionlinks": "($1) $2 $3",
@@ -8,6 +13,7 @@
"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",
@@ -22,5 +28,6 @@
"discord-uploadnewver": "new version of",
"discord-uploadcomplete": "$1 uploaded $2 $3 $4 ($5, $6x$7, $8)",
"discord-filedeletecomplete": "$1 deleted a version of file $2 $3",
"discord-fileundeletecomplete": "$1 restored some versions of file $2 $3"
"discord-fileundeletecomplete": "$1 restored some versions of file $2 $3",
"discord-timestampformat": "**H:i e:**"
}
+31
View File
@@ -0,0 +1,31 @@
{
"@metadata": {
"authors": [
"Railfail536"
]
},
"discord-desc": "Wysyła wiadomości o dokonywanych akcjach na serwer Discord",
"discord-userlinks": "$1 ($2|$3)",
"discord-revisionlinks": "($1) $2 $3",
"discord-talk": "d",
"discord-contribs": "w",
"discord-diff": "różn.",
"discord-minor": "(m)",
"discord-size": "($1)",
"discord-edit": "$1 edytował $2 $3 $4",
"discord-articledelete": "$1 usunął $2 $3 ($4 wersje usunięte)",
"discord-undeleterev": "wersje",
"discord-articleundelete": "$1 odtworzył $2 $3 $4",
"discord-revvisibility": "$1 zmienił widoczność $2 wersji $3",
"discord-articleprotect": "$1 zmienił poziom zabezpoeczenia strony $2 $2 $3 ($4)",
"discord-titlemove": "$1 przeniósł $2 na $3 $4 $5",
"discord-localusercreated": "$1 założył konto",
"discord-blocktimeformat": "d F Y H:i",
"discord-blockipcomplete": "$1 zablokował $2 $3 ($4)",
"discord-unblockusercomplete": "$1 zdjął blokadę z $2",
"discord-usergroupschanged": "$1 zmienił uprawnienia użytkownika $2 $3 ($4) ($5)",
"discord-uploadnewver": "nową wersję",
"discord-uploadcomplete": "$1 przesłał $2 $3 $4 ($5, $6x$7, $8)",
"discord-filedeletecomplete": "$1 usunął wersję pliku $2 $3",
"discord-fileundeletecomplete": "$1 odtworzył wersje pliku $2 $3"
}
+9 -2
View File
@@ -1,4 +1,9 @@
{
"@metadata": {
"authors": [
"Jayden Bailey"
]
},
"discord-desc": "The description used for the Discord extension",
"discord-userlinks": "Used for display of the user links. Parameters\n* $1 - User page link\n* $2 - discord-talk\n* $3 - discord-contribs",
"discord-revisionlinks": "Used for display of revision links. Parameters\n* $1 - discord-diff\n* $2 - discord-minor\n* $3 - discord-size",
@@ -7,7 +12,8 @@
"discord-diff": "Used as the text for $1 in discord-revisionlinks",
"discord-minor": "Used as the text for $2 in discord-revisionlinks",
"discord-size": "Used as the text for $3 in discord-revisionlinks. Parameters\n* $1 - Calculated revision size diff",
"discord-edit": "Message sent to Discord for when a page edit/creation is made. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - discord-revisionlinks\n* $4 - Summary (always surrounded in tildes)",
"discord-edit": "Message sent to Discord for when a page edit is made. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - discord-revisionlinks\n* $4 - Summary (always surrounded in tildes)",
"discord-create": "Message sent to Discord for when a page creation is made. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - discord-revisionlinks\n* $4 - Summary (always surrounded in tildes)",
"discord-articledelete": "Message sent to Discord when a page is deleted. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - Reason (always surrounded in tildes)\n* $4 - Number of revisions deleted",
"discord-undeleterev": "Used as the text for $2 in discord-articleundelete if revisions are being undeleted rather than a page",
"discord-articleundelete": "Message sent to Discord when pages/revisions are undeleted. Parameters:\n* $1 - discord-userlinks\n* $2 - discord-undeleterev\n* $3 - Page link\n* $4 - Comment (always surrounded in tildes)",
@@ -22,5 +28,6 @@
"discord-uploadnewver": "Used as the text for $2 in discord-uploadcomplete",
"discord-uploadcomplete": "Message sent to Discord when an upload is made. Parameters:\n$1 - discord-userlinks\n$2 - discord-uploadnewver\n$3 - File link\n$4 - Comment (always surrounded in tildes)\n$5 - Size (formatted as KB/MB/GB)\n$6 - File width\n$7 - File height\n$8 - File MIME type",
"discord-filedeletecomplete": "Message sent to Discord when a file version is deleted (not an entire file). Parameters:\n$1 - discord-userlinks\n$2 - File link\n$3 - Comment (always surrounded in tildes)",
"discord-fileundeletecomplete": "Message sent to Discord when a file version is restored (not an entire file). Parameters:\n$1 - discord-userlinks\n$2 - File link\n$3 - Comment (always surrounded in tildes)"
"discord-fileundeletecomplete": "Message sent to Discord when a file version is restored (not an entire file). Parameters:\n$1 - discord-userlinks\n$2 - File link\n$3 - Comment (always surrounded in tildes)",
"discord-timestampformat": "The formatting used in the gmtime() function for displaying the time an event happened in UTC."
}
+56 -18
View File
@@ -32,15 +32,22 @@ class DiscordHooks {
return true;
}
if ( $wikiPage->getTitle()->inNamespace( NS_FILE ) ) {
// Don't continue, it's a file which onUploadComplete will handle instead
if ( $wikiPage->getTitle()->inNamespace( NS_FILE ) && is_null( $revision->getPrevious() ) ) {
// Don't continue, it's a new file which onUploadComplete will handle instead
return true;
}
$msg = wfMessage( 'discord-edit', DiscordUtils::createUserLinks( $user ),
$msgKey = 'discord-edit';
$isNew = $status->value['new'];
if ($isNew == 1) { // is a new page
$msgKey = 'discord-create';
}
$msg = wfMessage( $msgKey, DiscordUtils::createUserLinks( $user ),
DiscordUtils::createMarkdownLink( $wikiPage->getTitle(), $wikiPage->getTitle()->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
DiscordUtils::createRevisionText( $revision ),
( $summary ? ('`' . DiscordUtils::truncateText( $summary ) . '`' ) : '' ) )->text();
( $summary ? ('`' . DiscordUtils::truncateText( $summary ) . '`' ) : '' ) )->plain();
DiscordUtils::handleDiscord($msg);
return true;
}
@@ -50,7 +57,7 @@ class DiscordHooks {
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleDeleteComplete
*/
public static function onArticleDeleteComplete( &$article, User &$user, $reason, $id, $content, LogEntry $logEntry, $archivedRevisionCount ) {
global $wgDiscordNoBots, $wgDiscordNoMinor, $wgDiscordNoNull;
global $wgDiscordNoBots;
if ( DiscordUtils::isDisabled( 'ArticleDeleteComplete', $article->getTitle()->getNamespace(), $user ) ) {
return true;
@@ -64,7 +71,7 @@ class DiscordHooks {
$msg = wfMessage( 'discord-articledelete', DiscordUtils::createUserLinks( $user ),
DiscordUtils::createMarkdownLink( $article->getTitle(), $article->getTitle()->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ),
$archivedRevisionCount)->text();
$archivedRevisionCount)->plain();
DiscordUtils::handleDiscord($msg);
return true;
}
@@ -74,16 +81,21 @@ class DiscordHooks {
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleUndelete
*/
public static function onArticleUndelete( Title $title, $create, $comment, $oldPageId, $restoredPages ) {
global $wgUser;
global $wgDiscordNoBots, $wgUser;
if ( DiscordUtils::isDisabled( 'ArticleUndelete', $title->getNamespace(), $wgUser ) ) {
return true;
}
if ( $wgDiscordNoBots && $wgUser->isBot() ) {
// Don't continue, this is a bot change
return true;
}
$msg = wfMessage( 'discord-articleundelete', DiscordUtils::createUserLinks( $wgUser ),
($create ? '' : wfMessage( 'discord-undeleterev' )->text() ),
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
( $comment ? ('`' . DiscordUtils::truncateText( $comment ) . '`' ) : '' ))->text();
( $comment ? ('`' . DiscordUtils::truncateText( $comment ) . '`' ) : '' ))->plain();
DiscordUtils::handleDiscord($msg);
return true;
}
@@ -93,15 +105,20 @@ class DiscordHooks {
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleRevisionVisibilitySet
*/
public static function onArticleRevisionVisibilitySet( &$title, $ids, $visibilityChangeMap ) {
global $wgUser;
global $wgDiscordNoBots, $wgUser;
if ( DiscordUtils::isDisabled( 'ArticleRevisionVisibilitySet', $title->getNamespace(), $wgUser ) ) {
return true;
}
if ( $wgDiscordNoBots && $wgUser->isBot() ) {
// Don't continue, this is a bot change
return true;
}
$msg = wfMessage( 'discord-revvisibility', DiscordUtils::createUserLinks( $wgUser ),
count($visibilityChangeMap),
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ) )->text();
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ) )->plain();
DiscordUtils::handleDiscord($msg);
return true;
}
@@ -125,7 +142,7 @@ class DiscordHooks {
$msg = wfMessage( 'discord-articleprotect', DiscordUtils::createUserLinks( $user ),
DiscordUtils::createMarkdownLink( $article->getTitle(), $article->getTitle()->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ),
implode(", ", $protect) )->text();
implode(", ", $protect) )->plain();
DiscordUtils::handleDiscord($msg);
return true;
}
@@ -150,7 +167,7 @@ class DiscordHooks {
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
DiscordUtils::createMarkdownLink( $newTitle, $newTitle->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ),
DiscordUtils::createRevisionText( $revision ) )->text();
DiscordUtils::createRevisionText( $revision ) )->plain();
DiscordUtils::handleDiscord($msg);
return true;
}
@@ -164,7 +181,7 @@ class DiscordHooks {
return true;
}
$msg = wfMessage( 'discord-localusercreated', DiscordUtils::createUserLinks( $user ) )->text();
$msg = wfMessage( 'discord-localusercreated', DiscordUtils::createUserLinks( $user ) )->plain();
DiscordUtils::handleDiscord($msg);
return true;
}
@@ -187,7 +204,7 @@ class DiscordHooks {
$msg = wfMessage( 'discord-blockipcomplete', DiscordUtils::createUserLinks( $user ), DiscordUtils::createUserLinks( $block->getTarget() ),
( $block->mReason ? ('`' . DiscordUtils::truncateText( $block->mReason ) . '`' ) : '' ),
$expiryMsg )->text();
$expiryMsg )->plain();
DiscordUtils::handleDiscord($msg);
return true;
}
@@ -224,7 +241,7 @@ class DiscordHooks {
DiscordUtils::createUserLinks( $user ),
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ),
( ( count($added) > 0 ) ? ( '+ ' . join(', ', $added) ) : ''),
( ( count($removed) > 0 ) ? ( '- ' . join(', ', $removed) ) : '' ) )->text();
( ( count($removed) > 0 ) ? ( '- ' . join(', ', $removed) ) : '' ) )->plain();
DiscordUtils::handleDiscord($msg);
return true;
}
@@ -234,6 +251,8 @@ class DiscordHooks {
* @see https://www.mediawiki.org/wiki/Manual:Hooks/UploadComplete
*/
public static function onUploadComplete( &$image ) {
global $wgDiscordNoBots;
$lf = $image->getLocalFile();
$user = $lf->getUser( $type = 'object' ); // only supported in MW 1.31+
@@ -241,6 +260,11 @@ class DiscordHooks {
return true;
}
if ( $wgDiscordNoBots && $user->isBot() ) {
// Don't continue, this is a bot change
return true;
}
$comment = $lf->getDescription();
$isNewRevision = count($lf->getHistory()) > 0;
@@ -251,7 +275,7 @@ class DiscordHooks {
DiscordUtils::formatBytes($lf->getSize()),
$lf->getWidth(),
$lf->getHeight(),
$lf->getMimeType() )->text();
$lf->getMimeType() )->plain();
DiscordUtils::handleDiscord($msg);
return true;
}
@@ -261,10 +285,17 @@ class DiscordHooks {
* @see https://www.mediawiki.org/wiki/Manual:Hooks/FileDeleteComplete
*/
public static function onFileDeleteComplete( $file, $oldimage, $article, $user, $reason ) {
global $wgDiscordNoBots;
if ( DiscordUtils::isDisabled( 'FileDeleteComplete', 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;
@@ -272,7 +303,7 @@ class DiscordHooks {
$msg = wfMessage( 'discord-filedeletecomplete', DiscordUtils::createUserLinks( $user ),
DiscordUtils::createMarkdownLink( $file->getName(), $file->getTitle()->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ) )->text();
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ) )->plain();
DiscordUtils::handleDiscord($msg);
return true;
}
@@ -282,13 +313,20 @@ class DiscordHooks {
* @see https://www.mediawiki.org/wiki/Manual:Hooks/FileUndeleteComplete
*/
public static function onFileUndeleteComplete( $title, $fileVersions, $user, $reason ) {
global $wgDiscordNoBots;
if ( DiscordUtils::isDisabled( 'FileUndeleteComplete', NS_FILE, $user ) ) {
return true;
}
if ( $wgDiscordNoBots && $user->isBot() ) {
// Don't continue, this is a bot change
return true;
}
$msg = wfMessage( 'discord-fileundeletecomplete', DiscordUtils::createUserLinks( $user ),
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ) )->text();
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ) )->plain();
DiscordUtils::handleDiscord($msg);
return true;
}
+71 -34
View File
@@ -46,7 +46,7 @@ class DiscordUtils {
* Handles sending a webhook to Discord using cURL
*/
public static function handleDiscord ($msg) {
global $wgDiscordWebhookURL;
global $wgDiscordWebhookURL, $wgDiscordPrependTimestamp, $wgDiscordUseFileGetContents;
if ( !$wgDiscordWebhookURL ) {
// There's nothing in here, so we won't do anything
@@ -67,41 +67,66 @@ class DiscordUtils {
// Strip whitespace to just one space
$stripped = preg_replace('/\s+/', ' ', $msg);
if ( $wgDiscordPrependTimestamp ) {
// Add timestamp
$dateString = gmdate( wfMessage( 'discord-timestampformat' )->text() );
$stripped = $dateString . ' ' . $stripped;
}
DeferredUpdates::addCallableUpdate( function() use ( $stripped, $urls ) {
$user_agent = 'mw-discord/1.0 (github.com/jaydenkieran)';
$json_data = [ 'content' => "$stripped" ];
$json = json_encode($json_data);
// Set up cURL multi handlers
$c_handlers = [];
$result = [];
$mh = curl_multi_init();
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
]
];
foreach ($urls as &$value) {
$c_handlers[$value] = curl_init( $value );
curl_setopt( $c_handlers[$value], CURLOPT_POST, 1 ); // Send as a POST request
curl_setopt( $c_handlers[$value], CURLOPT_POSTFIELDS, $json ); // Send the JSON in the POST request
curl_setopt( $c_handlers[$value], CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt( $c_handlers[$value], CURLOPT_HEADER, 0 );
curl_setopt( $c_handlers[$value], CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $c_handlers[$value], CURLOPT_CONNECTTIMEOUT, 10 ); // Add a timeout for connecting to the site
curl_setopt( $c_handlers[$value], CURLOPT_TIMEOUT, 20 ); // Do not allow cURL to run for a long time
curl_setopt( $c_handlers[$value], CURLOPT_USERAGENT, 'mw-discord/1.0 (github.com/jaydenkieran)' ); // Add a unique user agent
curl_multi_add_handle( $mh, $c_handlers[$value] );
$response = curl_exec( $ch );
$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_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);
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
}
$running = null;
do {
curl_multi_exec($mh, $running);
} while ($running);
// Remove all handlers and then close the multi handler
foreach($c_handlers as $k => $ch) {
$result[$k] = curl_multi_getcontent($ch);
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
} );
return true;
@@ -120,10 +145,19 @@ class DiscordUtils {
* Creates links for a specific MediaWiki User object
*/
public static function createUserLinks ($user) {
$userPage = DiscordUtils::createMarkdownLink( $user, $user->getUserPage()->getFullUrl( '', '', $proto = PROTO_HTTP ) );
$userTalk = DiscordUtils::createMarkdownLink( wfMessage( 'discord-talk' )->text(), $user->getTalkPage()->getFullUrl( '', '', $proto = PROTO_HTTP ) );
$userContribs = DiscordUtils::createMarkdownLink( wfMessage( 'discord-contribs' )->text(), Title::newFromText("Special:Contributions/" . $user)->getFullURL( '', '', $proto = PROTO_HTTP ) );
$text = wfMessage( 'discord-userlinks', $userPage, $userTalk, $userContribs )->text();
if ( $user instanceof User ) {
$isAnon = $user->isAnon();
$contribs = Title::newFromText("Special:Contributions/" . $user);
$userPage = DiscordUtils::createMarkdownLink( $user, ( $isAnon ? $contribs : $user->getUserPage() )->getFullUrl( '', '', $proto = PROTO_HTTP ) );
$userTalk = DiscordUtils::createMarkdownLink( wfMessage( 'discord-talk' )->text(), $user->getTalkPage()->getFullUrl( '', '', $proto = PROTO_HTTP ) );
$userContribs = DiscordUtils::createMarkdownLink( wfMessage( 'discord-contribs' )->text(), $contribs->getFullURL( '', '', $proto = PROTO_HTTP ) );
$text = wfMessage( 'discord-userlinks', $userPage, $userTalk, $userContribs )->text();
} else {
// If it's a string, which can be likely (for example when range blocking a user)
// We need to handle this differently.
$text = wfMessage( 'discord-userlinks', $user, 'n/a', 'n/a' )->text();
}
return $text;
}
@@ -147,6 +181,9 @@ class DiscordUtils {
$size .= wfMessage( 'discord-size', sprintf( "%+d", $revision->getSize() - $previous->getSize() ) )->text();
}
}
if ( $size == '' ) {
$size .= wfMessage( 'discord-size', sprintf( "%d", $revision->getSize() ) )->text();
}
$text = wfMessage( 'discord-revisionlinks', $diff, $minor, $size )->text();
return $text;
}