jenkins-bot has submitted this change and it was merged. (
https://gerrit.wikimedia.org/r/398659 )
Change subject: Refactor UserMiniProfile and UserProfileImage DFD-Module
......................................................................
Refactor UserMiniProfile and UserProfileImage DFD-Module
* Moved user setting to Extension:BlueSpiceAvatars
* Therefore BSF only handles "anon" and "default"
PatchSet 2:
* Implemeted CR by Mglaser
PatchSet 4:
* Added new hook base class 'PageHistoryLineEnding'
Change-Id: I4958c75cc66b5c9c863e0471ca3c5fe511dad0b1
---
M extension.json
M includes/outputhandler/views/view.UserMiniProfile.php
A src/DynamicFileDispatcher/AbstractStaticFile.php
M src/DynamicFileDispatcher/UserProfileImage.php
A src/DynamicFileDispatcher/UserProfileImage/AnonImage.php
A src/DynamicFileDispatcher/UserProfileImage/DefaultImage.php
D src/DynamicFileDispatcher/UserProfileImage/Image.php
D src/DynamicFileDispatcher/UserProfileImage/ImageExternal.php
A src/Hook/PageHistoryLineEnding.php
M src/ServicesDecorator.php
10 files changed, 202 insertions(+), 240 deletions(-)
Approvals:
Mglaser: Looks good to me, approved
jenkins-bot: Verified
diff --git a/extension.json b/extension.json
index d1d1ed8..018b210 100644
--- a/extension.json
+++ b/extension.json
@@ -480,6 +480,14 @@
},
"ConfigFiles": {
"value": []
+ },
+ "DefaultUserImage": {
+ "value":
"resources/bluespice/images/bs-user-default-image.png",
+ "path": true
+ },
+ "DefaultAnonImage": {
+ "value":
"resources/bluespice/images/bs-user-anon-image.png",
+ "path": true
}
},
"ConfigRegistry": {
diff --git a/includes/outputhandler/views/view.UserMiniProfile.php
b/includes/outputhandler/views/view.UserMiniProfile.php
index 5bc65b1..5c67d6b 100644
--- a/includes/outputhandler/views/view.UserMiniProfile.php
+++ b/includes/outputhandler/views/view.UserMiniProfile.php
@@ -1,7 +1,8 @@
<?php
-use MediaWiki\MediaWikiServices;
use BlueSpice\DynamicFileDispatcher\Params;
+use BlueSpice\Services;
+use BlueSpice\DynamicFileDispatcher\UserProfileImage;
/**
* This class provides a miniprofile for users.
* @package BlueSpice_AdapterMW
@@ -31,15 +32,14 @@
: $this->aDefaultClasses;
$params = array_merge( $this->mOptions, [
- Params::MODULE => 'userprofileimage',
- 'username' => $this->mOptions['user']->getName(),
+ Params::MODULE => UserProfileImage::MODULE_NAME,
+ UserProfileImage::USERNAME =>
$this->mOptions['user']->getName(),
+ UserProfileImage::WIDTH =>
(int)$this->mOptions['width'],
+ UserProfileImage::HEIGHT =>
(int)$this->mOptions['height']
]);
- $dfdUrlBuilder = MediaWikiServices::getInstance()->getService(
- 'BSDynamicFileDispatcherUrlBuilder'
- );
- $url = $dfdUrlBuilder->build(
- new Params( $params )
- );
+
+ $dfdUrlBuilder =
Services::getInstance()->getBSDynamicFileDispatcherUrlBuilder();
+ $url = $dfdUrlBuilder->build( new Params( $params ) );
$aOut = array();
$aOut[] = '<div class="'. implode( ' ', $aClasses ).'"
title="'.$this->mOptions['userdisplayname'].'">';
@@ -101,69 +101,6 @@
);
}
- if( empty( $this->mOptions['userimagesrc'] ) ) {
- $this->mOptions['userimagesrc'] =
$GLOBALS['wgScriptPath']
-
."/extensions/BlueSpiceFoundation/resources/bluespice/images/bs-user-default-image.png";
- }
-
- if ( $oUser->isAnon() ) {
- $this->mOptions['userimagesrc'] =
$GLOBALS['wgScriptPath']
-
."/extensions/BlueSpiceFoundation/resources/bluespice/images/bs-user-anon-image.png";
- $this->mOptions['linktargethref'] = '';
- } else {
- $sUserImageName = BsConfig::getVarForUser(
'MW::UserImage', $oUser );
- if ( !empty( $sUserImageName ) ) { //Image given as a
url
-
- if ( $sUserImageName{0} == '/' ) {
- //relative url from own system given
- $this->mOptions['userimagesrc'] =
$sUserImageName;
- } elseif ( $this->isExternalUrl(
$sUserImageName ) ) {
- $aParsedUrl = wfParseUrl(
$sUserImageName );
- //external url
- //TODO: Fix, when system is call via
https:// and the given
- //url is http:// the browser will block
the image
- $bAllowedProtocoll = in_array(
-
$aParsedUrl['scheme'].$aParsedUrl['delimiter'],
- $wgUrlProtocols
- );
- if( $bAllowedProtocoll ) {
- $sQuery = isset(
$aParsedUrl['query'] ) ?
-
"?{$aParsedUrl['query']}"
- : ''
- ;
- $this->mOptions['userimagesrc']
=
- $aParsedUrl['scheme']
-
.$aParsedUrl['delimiter']
- .$aParsedUrl['host']
- .$aParsedUrl['path']
- .$sQuery
- ;
- }
- } else {
- $this->setOptionsFromRepoFile(
$sUserImageName );
- }
- } else {
- //MW default File:<username>
- $oUserImageFile =
RepoGroup::singleton()->findFile(
- Title::newFromText( $sUserImageName,
NS_FILE )
- );
- $oUserThumbnail = false;
- if ( $oUserImageFile !== false ) {
- $oUserThumbnail =
$oUserImageFile->transform(
- array(
- 'width' =>
$this->mOptions['width'],
- 'height' =>
$this->mOptions['height']
- )
- );
- }
- if ( $oUserThumbnail !== false ) {
- $this->mOptions['userimagesrc'] =
$oUserThumbnail->getUrl();
- $this->mOptions['width'] =
$oUserThumbnail->getWidth();
- $this->mOptions['height'] =
$oUserThumbnail->getHeight();
- }
- }
- }
-
Hooks::run( 'UserMiniProfileAfterInit', array( $this ) );
$this->bIsInit = true;
}
@@ -178,26 +115,5 @@
public function getOptions() {
return $this->mOptions;
- }
-
- protected function isExternalUrl( $sMaybeExternalUrl ) {
- return substr( $sMaybeExternalUrl, 0, 4 ) == "http";
- }
-
- protected function setOptionsFromRepoFile( $sUserImageName ) {
- $oUserImageFile = wfFindFile( $sUserImageName );
- if( $oUserImageFile ) {
- $oUserThumbnail = $oUserImageFile->transform(
- array(
- 'width' => $this->mOptions['width'],
- 'height' => $this->mOptions['height']
- )
- );
- if ( $oUserThumbnail ) {
- $this->mOptions['userimagesrc'] =
$oUserThumbnail->getUrl();
- $this->mOptions['width'] =
$oUserThumbnail->getWidth();
- $this->mOptions['height'] =
$oUserThumbnail->getHeight();
- }
- }
}
}
\ No newline at end of file
diff --git a/src/DynamicFileDispatcher/AbstractStaticFile.php
b/src/DynamicFileDispatcher/AbstractStaticFile.php
new file mode 100644
index 0000000..5f06ac5
--- /dev/null
+++ b/src/DynamicFileDispatcher/AbstractStaticFile.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace BlueSpice\DynamicFileDispatcher;
+
+use BlueSpice\Services;
+
+abstract class AbstractStaticFile extends File {
+
+ /**
+ * @return string
+ */
+ public function getMimeType() {
+ $mimeAnalyzer = Services::getInstance()->getMimeAnalyzer();
+ return $mimeAnalyzer->guessMimeType( $this->getAbsolutePath() );
+ }
+
+ /**
+ * Sets the headers for given \WebResponse
+ * @param \WebResponse $response
+ * @return void
+ */
+ public function setHeaders( \WebResponse $response ) {
+ $response->header( 'Content-type: ' . $this->getMimeType(),
true );
+ readfile( $this->getAbsolutePath() );
+ }
+
+ /**
+ * @return string
+ */
+ protected abstract function getAbsolutePath();
+}
\ No newline at end of file
diff --git a/src/DynamicFileDispatcher/UserProfileImage.php
b/src/DynamicFileDispatcher/UserProfileImage.php
index 0dc9161..5e37624 100644
--- a/src/DynamicFileDispatcher/UserProfileImage.php
+++ b/src/DynamicFileDispatcher/UserProfileImage.php
@@ -2,10 +2,20 @@
namespace BlueSpice\DynamicFileDispatcher;
+use BlueSpice\DynamicFileDispatcher\UserProfileImage\AnonImage;
+use BlueSpice\DynamicFileDispatcher\UserProfileImage\DefaultImage;
+
class UserProfileImage extends Module {
+ const MODULE_NAME = 'userprofileimage';
const USERNAME = 'username';
const WIDTH = 'width';
const HEIGHT = 'height';
+
+ /**
+ *
+ * @var \User
+ */
+ protected $user = null;
public function getParamDefinition() {
return array_merge( parent::getParamDefinition(), [
@@ -37,39 +47,14 @@
}
}
- protected function getImageSource() {
- //This is temporay code until the UserMiniProfile gets a rewrite
- $miniprofile = \BsCore::getInstance()->getUserMiniProfile(
- \User::newFromName( $this->params[static::USERNAME] ),
- [
- 'width' => $this->params[static::WIDTH],
- 'height' => $this->params[static::HEIGHT],
- ]
- );
- $options = $miniprofile->getOptions();
- return $options['userimagesrc'];
- }
-
- protected function isExternalUrl( $sMaybeExternalUrl ) {
- return substr( $sMaybeExternalUrl, 0, 4 ) == "http";
- }
-
/**
* @return File
*/
public function getFile() {
- $imgSrc = $this->getImageSource();
- if( $this->isExternalUrl( $imgSrc ) ) {
- return new
\BlueSpice\DynamicFileDispatcher\UserProfileImage\ImageExternal(
- $this,
- $imgSrc,
- \User::newFromName(
$this->params[static::USERNAME] )
- );
+ $this->user = \User::newFromName(
$this->params[static::USERNAME] );
+ if( $this->user->isAnon() ) {
+ return new AnonImage( $this );
}
- return new
\BlueSpice\DynamicFileDispatcher\UserProfileImage\Image(
- $this,
- $imgSrc,
- \User::newFromName( $this->params[static::USERNAME] )
- );
+ return new DefaultImage( $this );
}
-}
\ No newline at end of file
+}
diff --git a/src/DynamicFileDispatcher/UserProfileImage/AnonImage.php
b/src/DynamicFileDispatcher/UserProfileImage/AnonImage.php
new file mode 100644
index 0000000..44b3e51
--- /dev/null
+++ b/src/DynamicFileDispatcher/UserProfileImage/AnonImage.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace BlueSpice\DynamicFileDispatcher\UserProfileImage;
+
+use \BlueSpice\DynamicFileDispatcher\Module;
+use BlueSpice\DynamicFileDispatcher\AbstractStaticFile;
+
+class AnonImage extends AbstractStaticFile {
+
+ protected function getAbsolutePath() {
+ return $this->dfd->getConfig()->get( 'DefaultAnonImage' );
+ }
+}
\ No newline at end of file
diff --git a/src/DynamicFileDispatcher/UserProfileImage/DefaultImage.php
b/src/DynamicFileDispatcher/UserProfileImage/DefaultImage.php
new file mode 100644
index 0000000..8af807f
--- /dev/null
+++ b/src/DynamicFileDispatcher/UserProfileImage/DefaultImage.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace BlueSpice\DynamicFileDispatcher\UserProfileImage;
+
+use \BlueSpice\DynamicFileDispatcher\Module;
+use BlueSpice\DynamicFileDispatcher\AbstractStaticFile;
+
+class DefaultImage extends AbstractStaticFile {
+
+ protected function getAbsolutePath() {
+ return $this->dfd->getConfig()->get( 'DefaultUserImage' );
+ }
+
+}
\ No newline at end of file
diff --git a/src/DynamicFileDispatcher/UserProfileImage/Image.php
b/src/DynamicFileDispatcher/UserProfileImage/Image.php
deleted file mode 100644
index 28d9ab2..0000000
--- a/src/DynamicFileDispatcher/UserProfileImage/Image.php
+++ /dev/null
@@ -1,64 +0,0 @@
-<?php
-
-namespace BlueSpice\DynamicFileDispatcher\UserProfileImage;
-use \BlueSpice\DynamicFileDispatcher\Module;
-
-class Image extends \BlueSpice\DynamicFileDispatcher\File {
- /**
- *
- * @var string
- */
- protected $src = '';
-
- /**
- *
- * @var \User
- */
- protected $user = null;
-
- /**
- *
- * @param Module $dfd
- * @param sring $src
- * @param \User $user
- */
- public function __construct( Module $dfd, $src, $user ) {
- parent::__construct( $dfd );
- $this->src = $src;
- $this->user = $user;
- }
-
- /**
- * Sets the headers for given \WebResponse
- * @param \WebResponse $response
- * @return void
- */
- public function setHeaders( \WebResponse $response ) {
- $response->header(
- 'Content-type: '.$this->getMimeType(),
- true
- );
- //This is temporay code until the UserMiniProfile gets a rewrite
- $path = $GLOBALS['IP'];
- $scriptPath = $this->dfd->getConfig()->get( 'ScriptPath' );
- if( $scriptPath && $scriptPath != "" ) {
- $countDirs = substr_count( $scriptPath, '/' );
- $i = 0;
- while( $i < $countDirs ) {
- $path = dirname( $path );
- $i++;
- }
- }
- $path = str_replace(
- '/nsfr_img_auth.php/',
- '/images/',
- \BsFileSystemHelper::normalizePath( $path.$this->src )
- );
-
- readfile( $path );
- }
-
- public function getMimeType() {
- return 'image/png';
- }
-}
\ No newline at end of file
diff --git a/src/DynamicFileDispatcher/UserProfileImage/ImageExternal.php
b/src/DynamicFileDispatcher/UserProfileImage/ImageExternal.php
deleted file mode 100644
index 1102dd2..0000000
--- a/src/DynamicFileDispatcher/UserProfileImage/ImageExternal.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-
-namespace BlueSpice\DynamicFileDispatcher\UserProfileImage;
-
-class ImageExternal extends Image {
-
- /**
- * Sets the headers for given \WebResponse
- * @param \WebResponse $response
- * @return void
- */
- public function setHeaders( \WebResponse $response ) {
- $this->dfd->getContext()->getRequest()->response()->header(
- "Location:$this->src",
- true
- );
- }
-
- public function getMimeType() {
- return '';
- }
-}
\ No newline at end of file
diff --git a/src/Hook/PageHistoryLineEnding.php
b/src/Hook/PageHistoryLineEnding.php
new file mode 100644
index 0000000..2aa98d9
--- /dev/null
+++ b/src/Hook/PageHistoryLineEnding.php
@@ -0,0 +1,81 @@
+<?php
+
+namespace BlueSpice\Hook;
+
+use BlueSpice\Hook;
+
+abstract class PageHistoryLineEnding extends Hook {
+
+ /**
+ *
+ * @var \HistoryPager
+ */
+ protected $history = null;
+
+ /**
+ *
+ * @var \stdClass
+ */
+ protected $row = null;
+
+ /**
+ *
+ * @var string
+ */
+ protected $s = '';
+
+ /**
+ *
+ * @var array
+ */
+ protected $classes = [];
+
+ /**
+ *
+ * @var array
+ */
+ protected $attribs = [];
+
+ /**
+ *
+ * @param \IContextSource $context
+ * @param \Config $config
+ * @param \HistoryPager $history
+ * @param \stdClass $row
+ * @param string $s
+ * @param array $classes
+ * @param array $attribs
+ */
+ public function __construct( $context, $config, $history, &$row, &$s,
&$classes, &$attribs ) {
+ parent::__construct( $context, $config );
+
+ $this->history = $history;
+ $this->row =& $row;
+ $this->s =& $s;
+ $this->classes =& $classes;
+ $this->attribs =& $attribs;
+ }
+
+ /**
+ *
+ * @param \HistoryPager $history
+ * @param \stdClass $row
+ * @param string $s
+ * @param string $classes
+ * @param array $attribs
+ * @return boolean
+ */
+ public static function callback( $history, &$row, &$s, &$classes,
&$attribs ) {
+ $className = static::class;
+ $hookHandler = new $className(
+ null,
+ null,
+ $history,
+ $row,
+ $s,
+ $classes,
+ $attribs
+ );
+ return $hookHandler->process();
+ }
+}
\ No newline at end of file
diff --git a/src/ServicesDecorator.php b/src/ServicesDecorator.php
index 07a4008..9f9f26c 100644
--- a/src/ServicesDecorator.php
+++ b/src/ServicesDecorator.php
@@ -93,7 +93,7 @@
* use getMainConfig() to get a Config instances.
*
* @since 1.27
- * @return Config
+ * @return \Config
*/
public function getBootstrapConfig() {
return $this->decoratedServices->getService( 'BootstrapConfig'
);
@@ -101,7 +101,7 @@
/**
* @since 1.27
- * @return ConfigFactory
+ * @return \ConfigFactory
*/
public function getConfigFactory() {
return $this->decoratedServices->getService( 'ConfigFactory' );
@@ -112,7 +112,7 @@
* This may or may not be the same object that is returned by
getBootstrapConfig().
*
* @since 1.27
- * @return Config
+ * @return \Config
*/
public function getMainConfig() {
return $this->decoratedServices->getService( 'MainConfig' );
@@ -120,7 +120,7 @@
/**
* @since 1.27
- * @return SiteLookup
+ * @return \SiteLookup
*/
public function getSiteLookup() {
return $this->decoratedServices->getService( 'SiteLookup' );
@@ -128,7 +128,7 @@
/**
* @since 1.27
- * @return SiteStore
+ * @return \SiteStore
*/
public function getSiteStore() {
return $this->decoratedServices->getService( 'SiteStore' );
@@ -136,7 +136,7 @@
/**
* @since 1.28
- * @return InterwikiLookup
+ * @return \InterwikiLookup
*/
public function getInterwikiLookup() {
return $this->decoratedServices->getService( 'InterwikiLookup'
);
@@ -144,7 +144,7 @@
/**
* @since 1.27
- * @return IBufferingStatsdDataFactory
+ * @return \IBufferingStatsdDataFactory
*/
public function getStatsdDataFactory() {
return $this->decoratedServices->getService(
'StatsdDataFactory' );
@@ -152,7 +152,7 @@
/**
* @since 1.27
- * @return EventRelayerGroup
+ * @return \EventRelayerGroup
*/
public function getEventRelayerGroup() {
return $this->decoratedServices->getService(
'EventRelayerGroup' );
@@ -160,7 +160,7 @@
/**
* @since 1.27
- * @return SearchEngine
+ * @return \SearchEngine
*/
public function newSearchEngine() {
// New engine object every time, since they keep state
@@ -169,7 +169,7 @@
/**
* @since 1.27
- * @return SearchEngineFactory
+ * @return \SearchEngineFactory
*/
public function getSearchEngineFactory() {
return $this->decoratedServices->getService(
'SearchEngineFactory' );
@@ -177,7 +177,7 @@
/**
* @since 1.27
- * @return SearchEngineConfig
+ * @return \SearchEngineConfig
*/
public function getSearchEngineConfig() {
return $this->decoratedServices->getService(
'SearchEngineConfig' );
@@ -185,7 +185,7 @@
/**
* @since 1.27
- * @return SkinFactory
+ * @return \SkinFactory
*/
public function getSkinFactory() {
return $this->decoratedServices->getService( 'SkinFactory' );
@@ -193,7 +193,7 @@
/**
* @since 1.28
- * @return LBFactory
+ * @return \LBFactory
*/
public function getDBLoadBalancerFactory() {
return $this->decoratedServices->getService(
'DBLoadBalancerFactory' );
@@ -201,7 +201,7 @@
/**
* @since 1.28
- * @return LoadBalancer The main DB load balancer for the local wiki.
+ * @return \LoadBalancer The main DB load balancer for the local wiki.
*/
public function getDBLoadBalancer() {
return $this->decoratedServices->getService( 'DBLoadBalancer' );
@@ -209,7 +209,7 @@
/**
* @since 1.28
- * @return WatchedItemStoreInterface
+ * @return \WatchedItemStoreInterface
*/
public function getWatchedItemStore() {
return $this->decoratedServices->getService( 'WatchedItemStore'
);
@@ -217,7 +217,7 @@
/**
* @since 1.28
- * @return WatchedItemQueryService
+ * @return \WatchedItemQueryService
*/
public function getWatchedItemQueryService() {
return $this->decoratedServices->getService(
'WatchedItemQueryService' );
@@ -225,7 +225,7 @@
/**
* @since 1.28
- * @return CryptRand
+ * @return \CryptRand
*/
public function getCryptRand() {
return $this->decoratedServices->getService( 'CryptRand' );
@@ -233,7 +233,7 @@
/**
* @since 1.28
- * @return CryptHKDF
+ * @return \CryptHKDF
*/
public function getCryptHKDF() {
return $this->decoratedServices->getService( 'CryptHKDF' );
@@ -241,7 +241,7 @@
/**
* @since 1.28
- * @return MediaHandlerFactory
+ * @return \MediaHandlerFactory
*/
public function getMediaHandlerFactory() {
return $this->decoratedServices->getService(
'MediaHandlerFactory' );
@@ -249,7 +249,7 @@
/**
* @since 1.28
- * @return MimeAnalyzer
+ * @return \MimeAnalyzer
*/
public function getMimeAnalyzer() {
return $this->decoratedServices->getService( 'MimeAnalyzer' );
@@ -257,7 +257,7 @@
/**
* @since 1.28
- * @return ProxyLookup
+ * @return \ProxyLookup
*/
public function getProxyLookup() {
return $this->decoratedServices->getService( 'ProxyLookup' );
@@ -265,7 +265,7 @@
/**
* @since 1.29
- * @return Parser
+ * @return \Parser
*/
public function getParser() {
return $this->decoratedServices->getService( 'Parser' );
@@ -273,7 +273,7 @@
/**
* @since 1.30
- * @return ParserCache
+ * @return \ParserCache
*/
public function getParserCache() {
return $this->decoratedServices->getService( 'ParserCache' );
@@ -281,7 +281,7 @@
/**
* @since 1.28
- * @return GenderCache
+ * @return \GenderCache
*/
public function getGenderCache() {
return $this->decoratedServices->getService( 'GenderCache' );
@@ -289,7 +289,7 @@
/**
* @since 1.28
- * @return LinkCache
+ * @return \LinkCache
*/
public function getLinkCache() {
return $this->decoratedServices->getService( 'LinkCache' );
@@ -297,7 +297,7 @@
/**
* @since 1.28
- * @return LinkRendererFactory
+ * @return \LinkRendererFactory
*/
public function getLinkRendererFactory() {
return $this->decoratedServices->getService(
'LinkRendererFactory' );
@@ -308,7 +308,7 @@
* if no custom options are needed
*
* @since 1.28
- * @return LinkRenderer
+ * @return \LinkRenderer
*/
public function getLinkRenderer() {
return $this->decoratedServices->getService( 'LinkRenderer' );
@@ -316,7 +316,7 @@
/**
* @since 1.28
- * @return TitleFormatter
+ * @return \TitleFormatter
*/
public function getTitleFormatter() {
return $this->decoratedServices->getService( 'TitleFormatter' );
@@ -324,7 +324,7 @@
/**
* @since 1.28
- * @return TitleParser
+ * @return \TitleParser
*/
public function getTitleParser() {
return $this->decoratedServices->getService( 'TitleParser' );
@@ -356,7 +356,7 @@
/**
* @since 1.28
- * @return VirtualRESTServiceClient
+ * @return \VirtualRESTServiceClient
*/
public function getVirtualRESTServiceClient() {
return $this->decoratedServices->getService(
'VirtualRESTServiceClient' );
@@ -380,7 +380,7 @@
/**
* @since 1.30
- * @return CommandFactory
+ * @return \CommandFactory
*/
public function getShellCommandFactory() {
return $this->decoratedServices->getService(
'ShellCommandFactory' );
--
To view, visit https://gerrit.wikimedia.org/r/398659
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I4958c75cc66b5c9c863e0471ca3c5fe511dad0b1
Gerrit-PatchSet: 4
Gerrit-Project: mediawiki/extensions/BlueSpiceFoundation
Gerrit-Branch: master
Gerrit-Owner: Robert Vogel <[email protected]>
Gerrit-Reviewer: Ljonka <[email protected]>
Gerrit-Reviewer: Mglaser <[email protected]>
Gerrit-Reviewer: Pwirth <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits