Jackmcbarn has uploaded a new change for review. https://gerrit.wikimedia.org/r/188503
Change subject: Expose user information to Lua ...................................................................... Expose user information to Lua Add mw.user, which allows viewing groups, blocks, and some other user info. Bug: T85419 Change-Id: I531196588e0f9aeb2a50e3ab2f3dcedfeb64a104 --- M Scribunto.php M engines/LuaCommon/LuaCommon.php A engines/LuaCommon/UserLibrary.php A engines/LuaCommon/lualib/mw.user.lua 4 files changed, 200 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Scribunto refs/changes/03/188503/1 diff --git a/Scribunto.php b/Scribunto.php index 0861049..430e66d 100644 --- a/Scribunto.php +++ b/Scribunto.php @@ -123,6 +123,7 @@ $wgAutoloadClasses['Scribunto_LuaTitleLibrary'] = $dir.'engines/LuaCommon/TitleLibrary.php'; $wgAutoloadClasses['Scribunto_LuaTextLibrary'] = $dir.'engines/LuaCommon/TextLibrary.php'; $wgAutoloadClasses['Scribunto_LuaHtmlLibrary'] = $dir.'engines/LuaCommon/HtmlLibrary.php'; +$wgAutoloadClasses['Scribunto_LuaUserLibrary'] = $dir.'engines/LuaCommon/UserLibrary.php'; /***** Configuration *****/ diff --git a/engines/LuaCommon/LuaCommon.php b/engines/LuaCommon/LuaCommon.php index f8a6e2e..ab89c19 100644 --- a/engines/LuaCommon/LuaCommon.php +++ b/engines/LuaCommon/LuaCommon.php @@ -14,6 +14,7 @@ 'mw.title' => 'Scribunto_LuaTitleLibrary', 'mw.text' => 'Scribunto_LuaTextLibrary', 'mw.html' => 'Scribunto_LuaHtmlLibrary', + 'mw.user' => 'Scribunto_LuaUserLibrary', ); /** diff --git a/engines/LuaCommon/UserLibrary.php b/engines/LuaCommon/UserLibrary.php new file mode 100644 index 0000000..199b8b9 --- /dev/null +++ b/engines/LuaCommon/UserLibrary.php @@ -0,0 +1,121 @@ +<?php + +class Scribunto_LuaUserLibrary extends Scribunto_LuaLibraryBase { + // Note these caches are naturally limited to + // $wgExpensiveParserFunctionLimit actual User objects because any + // addition calls incrementExpensiveFunctionCount() + private $userCache = array(); + private $idCache = array( 0 => null ); + + function register() { + $lib = array( + 'newUser' => array( $this, 'newUser' ), + 'getGroups' => array( $this, 'getGroups' ), + 'getImplicitGroups' => array( $this, 'getImplicitGroups' ), + ); + return $this->getEngine()->registerInterface( 'mw.user.lua', $lib, array() ); + } + + /** + * Handler for user.new + * + * Calls User::newFromId or User::newFromName as appropriate for the + * arguments. + * + * @param $text_or_id string|int User ID or name to fetch + * @return array Lua data + */ + function newUser( $text_or_id ) { + $type = $this->getLuaType( $text_or_id ); + if ( $type === 'string' ) { + $text_or_id = User::getCanonicalName( $text_or_id, false ); + if ( array_key_exists( $text_or_id, $this->userCache ) ) { + $user = $this->userCache[$text_or_id]; + } else { + $user = User::newFromName( $text_or_id, false ); + if ( !$user ) { + return array( null ); + } + $this->incrementExpensiveFunctionCount(); + if ( $user->isHidden() ) { + $user = User::newFromId( 0 ); + $user->setName( $text_or_id ); + } + } + } elseif ( $type === 'number' ) { + if ( array_key_exists( $text_or_id, $this->idCache ) ) { + $user = $this->idCache[$text_or_id]; + if ( !$user ) { + return array( null ); + } + } else { + $user = User::newFromId( $text_or_id ); + $this->incrementExpensiveFunctionCount(); + if ( !$user->loadFromId() || $user->isHidden() ) { + $this->idCache[$text_or_id] = null; + return null; + } + } + } else { + // This will always fail + $this->checkType( 'user.new', 1, $text_or_id, 'number or string' ); + } + + $this->userCache[$user->getName()] = $user; + if ( $user->getId() !== 0 ) { + $this->idCache[$user->getId()] = $user; + } + + $retval = array( + 'id' => $user->getId(), + 'name' => $user->getName(), + ); + if ( $user->isLoggedIn() ) { + $retval['registration'] = $user->getRegistration(); + $retval['canReceiveEmail'] = $user->canReceiveEmail(); + } + // We already had to load the block to see if the user was hidden, + // so we might as well give this information to them now. + $block = $user->getBlock(); + if ( $block && !$block->mHideName && $block->getType() !== Block::TYPE_AUTO ) { + // @todo add support for detecting rangeblocks + $retval['block'] = array( + 'reason' => $block->mReason, + 'timestamp' => $block->mTimestamp, + 'expiry' => $block->getExpiry(), + 'id' => $block->getId(), + 'blockEmail' => $block->prevents('sendemail'), + 'disableUsertalk' => $block->prevents('editownusertalk'), + 'createAccount' => $block->prevents('createaccount'), + 'isHardblock' => $block->isHardblock(), + 'isAutoblocking' => $block->isAutoblocking(), + 'blockerId' => $block->getBy(), + 'blockerName' => $block->getByName(), + ); + } + return array( $retval ); + } + + public function getGroups( $text ) { + $this->checkType( 'getGroups', 1, $text, 'string' ); + $user = $this->userCache[$text]; + if ( !$user ) { + // This should never happen, but just in case... + return array( null ); + } + if ( is_null( $user->mGroups ) ) { + $this->incrementExpensiveFunctionCount(); + } + return array( array_fill_keys( $user->getGroups(), true ) ); + } + + public function getImplicitGroups( $text ) { + $this->checkType( 'getImplicitGroups', 1, $text, 'string' ); + $user = $this->userCache[$text]; + if ( !$user ) { + // This should never happen, but just in case... + return array( null ); + } + return array( array_fill_keys( $user->getAutomaticGroups(), true ) ); + } +} diff --git a/engines/LuaCommon/lualib/mw.user.lua b/engines/LuaCommon/lualib/mw.user.lua new file mode 100644 index 0000000..19249e8 --- /dev/null +++ b/engines/LuaCommon/lualib/mw.user.lua @@ -0,0 +1,77 @@ +local user = {} +local php + +function user.new( text_or_id ) + data = php.newUser( text_or_id ) + if not data then + return nil + end + + -- Known fields, both those set by PHP and any dynamically handled in + -- __index. True values represent read-only, and false values represent + -- read-write. + local readOnlyFields = { + groups = true, + implicitGroups = true, + } + for k in pairs( data ) do + readOnlyFields[k] = true + end + + local function pairsfunc( t, k ) + local v + repeat + k = next( readOnlyFields, k ) + if k == nil then + return nil + end + v = t[k] + until v ~= nil + return k, v + end + + return setmetatable( {}, { + __pairs = function ( t ) + return pairsfunc, t, nil + end, + __index = function ( t, k ) + if k == 'groups' then + if data.groups == nil then + data.groups = php.getGroups( data.name ) + end + elseif k == 'implicitGroups' then + if data.implicitGroups == nil then + data.implicitGroups = php.getImplicitGroups( data.name ) + end + end + + return data[k] + end, + __newindex = function ( t, k, v ) + if readOnlyFields[k] then + error( "index '" .. k .. "' is read only", 2 ) + else + readOnlyFields[k] = v and false -- assigns nil if v == nil, false otherwise + rawset( t, k, v ) + end + end, + __tostring = function ( t ) + return t.name + end + } ) +end + +function user.setupInterface( options ) + -- Boilerplate + user.setupInterface = nil + php = mw_interface + mw_interface = nil + + -- Register this library in the "mw" global + mw = mw or {} + mw.user = user + + package.loaded['mw.user'] = user +end + +return user -- To view, visit https://gerrit.wikimedia.org/r/188503 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I531196588e0f9aeb2a50e3ab2f3dcedfeb64a104 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Scribunto Gerrit-Branch: master Gerrit-Owner: Jackmcbarn <jackmcb...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits