Robert Vogel has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/398663 )
Change subject: Use of DFD module and some new features ...................................................................... Use of DFD module and some new features * Now usind DFD module * Added new tag <userimage> that allows to have user images in wikitext * Added user option (with preview) for profile image (formerly in BSF) * Added profile image to every user-page link (this is probably a bad idea; maybe just add it to history view, using a different hook) * Removed obsolete setting "DefaultSize" TODO: * Use a mustache template for the image * Handle width/height properly * Add config var for LinkEnd feature Change-Id: I39523a2dceaeb17a5e26aa705bc579665e264528 --- M extension.json M i18n/en.json M i18n/qqq.json A src/Config.php D src/ConfigDefinition/AvatarsDefaultSize.php A src/DynamicFileDispatcher/Image.php A src/DynamicFileDispatcher/ImageExternal.php A src/DynamicFileDispatcher/UserProfileImage.php M src/Generator.php D src/Hook/BSCoreGetUserMiniProfileBeforeInit/SetAvatar.php A src/Hook/GetPreferences/AddProfileImage.php A src/Hook/LinkEnd/AddUserImage.php A src/Hook/ParserFirstCallInit/AddUserImageTag.php A src/Html/FormField/UserImage.php A src/Html/ProfileImage.php A src/Tag/UserImage.php 16 files changed, 426 insertions(+), 67 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/BlueSpiceAvatars refs/changes/63/398663/1 diff --git a/extension.json b/extension.json index 1136107..9de7bdd 100644 --- a/extension.json +++ b/extension.json @@ -16,10 +16,12 @@ "className": "Avatars", "extPath": "/BlueSpiceAvatars", "configDefinitions": { - "AvatarsDefaultSize": "\\BlueSpice\\Avatars\\ConfigDefinition\\AvatarsDefaultSize::getInstance", "AvatarsGenerator": "\\BlueSpice\\Avatars\\ConfigDefinition\\AvatarsGenerator::getInstance" } } + }, + "DynamicFileRegistry": { + "userprofileimage": "\\BlueSpice\\Avatars\\DynamicFileDispatcher\\UserProfileImage" } } }, @@ -66,17 +68,19 @@ }, "config_prefix": "bsg", "config": { - "AvatarsDefaultSize": { - "value": 40 - }, "AvatarsGenerator": { "value": "InstantAvatar" } }, + "DefaultUserOptions": { + "bs-avatars-profileimage": "" + }, "Hooks": { "BeforePageDisplay": "\\BlueSpice\\Avatars\\Hook\\BeforePageDisplay\\AddModules::callback", - "UnitTestsList": "Avatars::onUnitTestsList", - "BSCoreGetUserMiniProfileBeforeInit": "\\BlueSpice\\Avatars\\Hook\\BSCoreGetUserMiniProfileBeforeInit\\SetAvatar::callback" + "GetPreferences": "\\BlueSpice\\Avatars\\Hook\\GetPreferences\\AddProfileImage::callback", + "ParserFirstCallInit": "\\BlueSpice\\Avatars\\Hook\\ParserFirstCallInit\\AddUserImageTag::callback", + "LinkEnd": "\\BlueSpice\\Avatars\\Hook\\LinkEnd\\AddUserImage::callback", + "UnitTestsList": "Avatars::onUnitTestsList" }, "load_composer_autoloader": true, "manifest_version": 2 diff --git a/i18n/en.json b/i18n/en.json index 88f1ac2..f0e16a1 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -9,6 +9,8 @@ "bs-avatars-desc": "Provides generic and individual user pictures", "bs-avatars-pref-generator": "Generator:", "bs-avatars-pref-defaultsize": "Default size in pixel:", + "bs-avatars-pref-userimage": "User image:", + "bs-avatars-pref-userimage-img-alt": "Your current user image", "bs-avatars-upload-complete": "The picture was uploaded.", "bs-avatars-generate-complete": "A new avatar was generated.", "bs-avatars-upload-title": "Change profile picture", diff --git a/i18n/qqq.json b/i18n/qqq.json index 556ca64..b2aa81a 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -9,6 +9,8 @@ "bs-avatars-desc": "Used in [{{canonicalurl:Special:WikiAdmin|mode=ExtensionInfo}} Special:WikiAdmin?mode=ExtensionInfo], description of avatars extension", "bs-avatars-pref-generator": "Option in [{{canonicalurl:Special:WikiAdmin|mode=Preferences}} Special:WikiAdmin?mode=Preferences], label for avatar generator:\n{{Identical|Generator}}", "bs-avatars-pref-defaultsize": "Option in [{{canonicalurl:Special:WikiAdmin|mode=Preferences}} Special:WikiAdmin?mode=Preferences], label for default size of avatar in pixel:", + "bs-avatars-pref-userimage": "Option in [{{canonicalurl:Special:Preferences}} Special:Preferences], label for user image:", + "bs-avatars-pref-userimage-img-alt": "Alt text for the user image in [[Special:Preferences]]", "bs-avatars-upload-complete": "Text for the picture was uploaded successfully.", "bs-avatars-generate-complete": "Text for a new avatar was generated.", "bs-avatars-upload-title": "Window title for change profile picture", diff --git a/src/Config.php b/src/Config.php new file mode 100644 index 0000000..a0a746b --- /dev/null +++ b/src/Config.php @@ -0,0 +1,8 @@ +<?php + +namespace BlueSpice\Avatars; + +class Config { + const DEFAULT_SIZE = 'AvatarsDefaultSize'; + const GENERATOR = 'AvatarsGenerator'; +} \ No newline at end of file diff --git a/src/ConfigDefinition/AvatarsDefaultSize.php b/src/ConfigDefinition/AvatarsDefaultSize.php deleted file mode 100644 index c7b8632..0000000 --- a/src/ConfigDefinition/AvatarsDefaultSize.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php - -namespace BlueSpice\Avatars\ConfigDefinition; - -class AvatarsDefaultSize extends \BlueSpice\ConfigDefinition\IntSetting { - - public function getLabelMessageKey() { - return 'bs-avatars-pref-defaultsize'; - } -} diff --git a/src/DynamicFileDispatcher/Image.php b/src/DynamicFileDispatcher/Image.php new file mode 100644 index 0000000..cd7ba35 --- /dev/null +++ b/src/DynamicFileDispatcher/Image.php @@ -0,0 +1,65 @@ +<?php + +namespace BlueSpice\Avatars\DynamicFileDispatcher; + +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/ImageExternal.php b/src/DynamicFileDispatcher/ImageExternal.php new file mode 100644 index 0000000..ccbd20a --- /dev/null +++ b/src/DynamicFileDispatcher/ImageExternal.php @@ -0,0 +1,22 @@ +<?php + +namespace BlueSpice\Avatars\DynamicFileDispatcher; + +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/DynamicFileDispatcher/UserProfileImage.php b/src/DynamicFileDispatcher/UserProfileImage.php new file mode 100644 index 0000000..24ab5f3 --- /dev/null +++ b/src/DynamicFileDispatcher/UserProfileImage.php @@ -0,0 +1,61 @@ +<?php + +namespace BlueSpice\Avatars\DynamicFileDispatcher; + +use BlueSpice\Avatars\Generator; +use BlueSpice\DynamicFileDispatcher\UserProfileImage as UPI; +use BlueSpice\Avatars\Config; +use BlueSpice\DynamicFileDispatcher\UserProfileImage\AnonImage; + +class UserProfileImage extends UPI { + + /** + * + * @return Image|ImageExternal + */ + public function getFile() { + $file = parent::getFile(); + if( $file instanceof AnonImage ) { + return $file; + } + + $profileImage = $this->user->getOption( 'bs-avatars-profileimage' ); + if( empty( $profileImage ) ) { + return $this->getDefaultUserImageFile(); + } + + if( wfParseUrl( $profileImage ) !== false ) { + return new ImageExternal( $this, $profileImage, $this->user ); + } + + $repoFile = \RepoGroup::singleton()->findFile( $profileImage ); + if( $repoFile === false || !$repoFile->exists() ) { + return $this->getDefaultUserImageFile(); + } + + $width = $this->params[static::WIDTH]; + $height = $this->params[static::HEIGHT]; + + $thumburl = $repoFile->createThumb( $width, $height ); + return new Image( $this, $thumburl, $this->user ); + } + + /** + * + * @return Image + */ + protected function getDefaultUserImageFile() { + $generator = new Generator( $this->getConfig() ); + $file = $generator->getAvatarFile( $this->user ); + if( !$file->exists() ) { + $generator->generate( $this->user ); + } + + $thumburl = $file->createThumb( + $this->params[UPI::WIDTH], + $this->params[UPI::HEIGHT] + ); + + return new Image( $this, $thumburl, $this->user ); + } +} \ No newline at end of file diff --git a/src/Generator.php b/src/Generator.php index 8ceef44..b98a4d7 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -17,10 +17,10 @@ /** * - * @param \Contig $contig + * @param \Config $config */ - public function __construct( $contig ) { - $this->config = $contig; + public function __construct( $config ) { + $this->config = $config; } /** @@ -83,18 +83,6 @@ $user->invalidateCache(); } - - $iAvatarHeight = empty( $params[static::PARAM_HEIGHT] ) - ? $this->config->get( 'AvatarsDefaultSize' ) - : $params[static::PARAM_HEIGHT] - ; - - $iAvatarWidth = empty( $params[static::PARAM_WIDTH] ) - ? $this->config->get( 'AvatarsDefaultSize' ) - : $params[static::PARAM_WIDTH] - ; - - return $oFile->createThumb( $iAvatarWidth, $iAvatarHeight ); } protected function generateIdention( \User $user, $size ) { diff --git a/src/Hook/BSCoreGetUserMiniProfileBeforeInit/SetAvatar.php b/src/Hook/BSCoreGetUserMiniProfileBeforeInit/SetAvatar.php deleted file mode 100644 index 904ed85..0000000 --- a/src/Hook/BSCoreGetUserMiniProfileBeforeInit/SetAvatar.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php - -namespace BlueSpice\Avatars\Hook\BSCoreGetUserMiniProfileBeforeInit; -use BlueSpice\Hook\BSCoreGetUserMiniProfileBeforeInit; -use BlueSpice\Avatars\Generator; - -/** - * Set avatar image if user has no UserImage setting - */ -class SetAvatar extends BSCoreGetUserMiniProfileBeforeInit { - - protected function skipProcessing() { - if( $this->user->isAnon() ) { - return true; - } - if( !empty( $this->user->getOption( 'MW::UserImage' ) ) ) { - return true; - } - if( wfReadOnly() ) { - return true; - } - - return false; - } - - protected function doProcess() { - $generator = new Generator( $this->getConfig() ); - $this->userMiniProfileView->setUserImageSrc( $generator->generate( - $this->user, - $this->params - )); - - return true; - } - -} \ No newline at end of file diff --git a/src/Hook/GetPreferences/AddProfileImage.php b/src/Hook/GetPreferences/AddProfileImage.php new file mode 100644 index 0000000..7db1bc8 --- /dev/null +++ b/src/Hook/GetPreferences/AddProfileImage.php @@ -0,0 +1,18 @@ +<?php + +namespace BlueSpice\Avatars\Hook\GetPreferences; + +use BlueSpice\Hook\GetPreferences; +use BlueSpice\Avatars\Html\FormField\UserImage; + +class AddProfileImage extends GetPreferences { + + protected function doProcess() { + $this->preferences['bs-avatars-profileimage'] = [ + 'section' => 'personal/info', + 'class' => UserImage::class + ]; + return true; + } + +} \ No newline at end of file diff --git a/src/Hook/LinkEnd/AddUserImage.php b/src/Hook/LinkEnd/AddUserImage.php new file mode 100644 index 0000000..87dbd04 --- /dev/null +++ b/src/Hook/LinkEnd/AddUserImage.php @@ -0,0 +1,26 @@ +<?php + +namespace BlueSpice\Avatars\Hook\LinkEnd; + +use BlueSpice\Hook\LinkEnd; +use BlueSpice\Avatars\Html\ProfileImage; + +class AddUserImage extends LinkEnd { + protected function doProcess() { + if( $this->target->getNamespace() !== NS_USER || $this->target->isSubpage() ) { + return true; + } + + $user = \User::newFromName( $this->target->getText() ); + if( !$user ) { + //in rare cases $this->target->getText() returns '127.0.0.1' which + //results in 'false' in User::newFromName + return true; + } + + $image = new ProfileImage( $user, 32, 32 ); + $this->html = $image->getHtml() . $this->html; + + return true; + } +} \ No newline at end of file diff --git a/src/Hook/ParserFirstCallInit/AddUserImageTag.php b/src/Hook/ParserFirstCallInit/AddUserImageTag.php new file mode 100644 index 0000000..fd60995 --- /dev/null +++ b/src/Hook/ParserFirstCallInit/AddUserImageTag.php @@ -0,0 +1,17 @@ +<?php + +namespace BlueSpice\Avatars\Hook\ParserFirstCallInit; + +use BlueSpice\Hook\ParserFirstCallInit; +use BlueSpice\Avatars\Tag\UserImage; + +class AddUserImageTag extends ParserFirstCallInit { + + protected function doProcess() { + $this->parser->setHook( + 'userimage', + [ UserImage::class, "callback"] + ); + return true; + } +} \ No newline at end of file diff --git a/src/Html/FormField/UserImage.php b/src/Html/FormField/UserImage.php new file mode 100644 index 0000000..7123609 --- /dev/null +++ b/src/Html/FormField/UserImage.php @@ -0,0 +1,35 @@ +<?php + +namespace BlueSpice\Avatars\Html\FormField; + +use BlueSpice\Services; +use BlueSpice\Avatars\DynamicFileDispatcher\UserProfileImage; +use BlueSpice\DynamicFileDispatcher\Params; + +class UserImage extends \HTMLTextField { + public function getLabel() { + return wfMessage( 'bs-avatars-pref-userimage' )->parse(); + } + + public function getInputHTML( $value ) { + $params = [ + Params::MODULE => UserProfileImage::MODULE_NAME, + UserProfileImage::USERNAME => $this->mParent->getUser()->getName(), + UserProfileImage::WIDTH => 128, + UserProfileImage::HEIGHT => 128 + ]; + + $dfdUrlBuilder = Services::getInstance()->getBSDynamicFileDispatcherUrlBuilder(); + $url = $dfdUrlBuilder->build( new Params( $params ) ); + + $html = \Html::element( 'img', [ + 'src' => $url, + 'alt' => wfMessage( 'bs-avatars-pref-userimage-img-alt' )->text(), + 'class' => 'bs-avatars-userimage', + 'style' => 'margin-right: 0.8em' + ]); + $html .= parent::getInputHTML( $value ); + + return $html; + } +} \ No newline at end of file diff --git a/src/Html/ProfileImage.php b/src/Html/ProfileImage.php new file mode 100644 index 0000000..38d3250 --- /dev/null +++ b/src/Html/ProfileImage.php @@ -0,0 +1,70 @@ +<?php + +namespace BlueSpice\Avatars\Html; + +use BlueSpice\DynamicFileDispatcher\UrlBuilder; +use BlueSpice\Services; +use BlueSpice\DynamicFileDispatcher\Params; +use BlueSpice\Avatars\DynamicFileDispatcher\UserProfileImage; + +class ProfileImage { + + /** + * + * @var \User + */ + protected $user = null; + + /** + * + * @var int + */ + protected $width = 32; + + /** + * + * @var int + */ + protected $height = 32; + + /** + * + * @var UrlBuilder + */ + protected $urlBuilder = null; + + /** + * + * @param \User $user + * @param int $width + * @param int $height + * @param UrlBuilder $urlBuilder + */ + public function __construct( $user, $width = 32, $height = 32, $urlBuilder = null ) { + $this->user = $user; + $this->width = $width; + $this->height = $height; + $this->urlBuilder = $urlBuilder; + if( $urlBuilder === null ) { + $this->urlBuilder = Services::getInstance() + ->getBSDynamicFileDispatcherUrlBuilder(); + } + } + + public function getHtml() { + $params = new Params( [ + Params::MODULE => UserProfileImage::MODULE_NAME, + UserProfileImage::USERNAME => $this->user->getName(), + UserProfileImage::WIDTH => $this->width, + UserProfileImage::HEIGHT => $this->height + ] ); + + $attribs = [ + 'src' => $this->urlBuilder->build( $params ), + 'width' => $this->width, + 'height' => $this->height, + 'alt' => 'TBD' + ]; + return \Html::element( 'img', $attribs ); + } +} \ No newline at end of file diff --git a/src/Tag/UserImage.php b/src/Tag/UserImage.php new file mode 100644 index 0000000..1c60523 --- /dev/null +++ b/src/Tag/UserImage.php @@ -0,0 +1,87 @@ +<?php + +namespace BlueSpice\Avatars\Tag; + +use BlueSpice\Services; +use BlueSpice\DynamicFileDispatcher\Params; +use BlueSpice\Avatars\DynamicFileDispatcher\UserProfileImage; + +class UserImage { + + /** + * + * @var string + */ + protected $input = ''; + + /** + * + * @var array + */ + protected $args = []; + + /** + * + * @var \Parser + */ + protected $parser = null; + + /** + * + * @var \PPFrame + */ + protected $frame = null; + + /** + * + * @param string $input + * @param array $args + * @param \Parser $parser + * @param \PPFrame $frame + */ + public function __construct( $input, array $args, \Parser $parser, \PPFrame $frame ) { + $this->input = $input; + $this->args = $args; + $this->parser = $parser; + $this->frame = $frame; + } + + /** + * + * @param string $input + * @param array $args + * @param \Parser $parser + * @param \PPFrame $frame + * @return string|array + */ + public static function callback( $input, array $args, \Parser $parser, \PPFrame $frame ) { + $handler = new static( $input, $args, $parser, $frame ); + return $handler->handle(); + } + + public function handle() { + $username = isset( $this->args['name'] ) ? $this->args['name'] : 'A'; + $width = isset( $this->args['width'] ) ? (int)$this->args['width'] : 32; + $height = isset( $this->args['height'] ) ? (int)$this->args['height'] : 32; + + $params = [ + Params::MODULE => UserProfileImage::MODULE_NAME, + UserProfileImage::USERNAME => $username, + UserProfileImage::WIDTH => $width, + UserProfileImage::HEIGHT => $height + ]; + + $dfdUrlBuilder = Services::getInstance()->getBSDynamicFileDispatcherUrlBuilder(); + $url = $dfdUrlBuilder->build( new Params( $params ) ); + + $html = \Html::element( 'img', [ + 'src' => $url, + 'alt' => wfMessage( 'bs-avatars-tag-userimage-img-alt', $username )->text(), + 'class' => 'bs-avatars-userimage-tag', + 'width' => $width, + 'height' => $height + ]); + + return $html; + } +} \ No newline at end of file -- To view, visit https://gerrit.wikimedia.org/r/398663 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I39523a2dceaeb17a5e26aa705bc579665e264528 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/BlueSpiceAvatars Gerrit-Branch: master Gerrit-Owner: Robert Vogel <vo...@hallowelt.biz> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits