2020-04-28 21:02:15 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
|
|
*
|
|
|
|
* @file
|
|
|
|
* @since 1.35
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace Vector;
|
|
|
|
|
|
|
|
use Config;
|
2021-11-23 13:40:35 +00:00
|
|
|
use MediaWiki\User\UserOptionsLookup;
|
2020-04-28 21:02:15 +00:00
|
|
|
use User;
|
|
|
|
use WebRequest;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given initial dependencies, retrieve the current skin version. This class does no parsing, just
|
|
|
|
* the lookup.
|
|
|
|
*
|
|
|
|
* Skin version is evaluated in the following order:
|
|
|
|
*
|
|
|
|
* - useskinversion URL query parameter override. See readme.
|
|
|
|
*
|
|
|
|
* - User preference. The User object for new accounts is updated (persisted as a user preference)
|
|
|
|
* by hook according to VectorDefaultSkinVersionForNewAccounts. See Hooks and skin.json. The user
|
|
|
|
* may then change the preference at will.
|
|
|
|
*
|
|
|
|
* - Site configuration default. The default is controlled by VectorDefaultSkinVersion and
|
|
|
|
* VectorDefaultSkinVersionForExistingAccounts based on login state. The former is used
|
|
|
|
* for anonymous users and as a fallback configuration, the latter is logged in users (existing
|
|
|
|
* accounts). See skin.json.
|
|
|
|
*
|
|
|
|
* @unstable
|
|
|
|
*
|
|
|
|
* @package Vector
|
|
|
|
* @internal
|
|
|
|
*/
|
|
|
|
final class SkinVersionLookup {
|
|
|
|
/**
|
|
|
|
* @var WebRequest
|
|
|
|
*/
|
|
|
|
private $request;
|
|
|
|
/**
|
|
|
|
* @var User
|
|
|
|
*/
|
|
|
|
private $user;
|
|
|
|
/**
|
|
|
|
* @var Config
|
|
|
|
*/
|
|
|
|
private $config;
|
2021-11-23 13:40:35 +00:00
|
|
|
/**
|
|
|
|
* @var UserOptionsLookup
|
|
|
|
*/
|
|
|
|
private $userOptionsLookup;
|
2020-04-28 21:02:15 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This constructor accepts all dependencies needed to obtain the skin version. The dependencies
|
|
|
|
* are lazily evaluated, not cached, meaning they always return the current results.
|
|
|
|
*
|
|
|
|
* @param WebRequest $request
|
|
|
|
* @param User $user
|
|
|
|
* @param Config $config
|
2021-11-23 13:40:35 +00:00
|
|
|
* @param UserOptionsLookup $userOptionsLookup
|
2020-04-28 21:02:15 +00:00
|
|
|
*/
|
2021-11-23 13:40:35 +00:00
|
|
|
public function __construct(
|
|
|
|
WebRequest $request,
|
|
|
|
User $user,
|
|
|
|
Config $config,
|
|
|
|
UserOptionsLookup $userOptionsLookup
|
|
|
|
) {
|
2020-04-28 21:02:15 +00:00
|
|
|
$this->request = $request;
|
|
|
|
$this->user = $user;
|
|
|
|
$this->config = $config;
|
2021-11-23 13:40:35 +00:00
|
|
|
$this->userOptionsLookup = $userOptionsLookup;
|
2020-04-28 21:02:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Whether or not the legacy skin is being used.
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
* @throws \ConfigException
|
|
|
|
*/
|
|
|
|
public function isLegacy(): bool {
|
|
|
|
return $this->getVersion() === Constants::SKIN_VERSION_LEGACY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The skin version as a string. E.g., `Constants::SKIN_VERSION_LATEST`,
|
|
|
|
* `Constants::SKIN_VERSION_LATEST`, or maybe 'beta'. Note: it's likely someone will put arbitrary
|
|
|
|
* strings in the query parameter which means this function returns those strings as is.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
* @throws \ConfigException
|
|
|
|
*/
|
|
|
|
public function getVersion(): string {
|
2022-01-18 22:44:19 +00:00
|
|
|
$migrationMode = $this->config->get( 'VectorSkinMigrationMode' );
|
|
|
|
// In migration mode, the useskin parameter is the source of truth.
|
|
|
|
if ( $migrationMode ) {
|
|
|
|
$useSkin = $this->request->getVal(
|
|
|
|
Constants::QUERY_PARAM_SKIN
|
|
|
|
);
|
|
|
|
if ( $useSkin ) {
|
|
|
|
return $useSkin === Constants::SKIN_NAME_LEGACY ?
|
|
|
|
Constants::SKIN_VERSION_LEGACY :
|
|
|
|
Constants::SKIN_VERSION_LATEST;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-09 22:13:48 +00:00
|
|
|
// If skin key is not vector, then version should be considered legacy.
|
|
|
|
|
|
|
|
// If skin is "Vector" invoke additional skin versioning detection.
|
2020-04-28 21:02:15 +00:00
|
|
|
// Obtain the skin version from the 1) `useskinversion` URL query parameter override, 2) the
|
|
|
|
// user preference, 3) the configured default for logged in users, 4) or the site default.
|
|
|
|
//
|
|
|
|
// The latter two configurations cannot be set by `Hooks::onUserGetDefaultOptions()` as user
|
|
|
|
// sessions are unavailable at that time so it's not possible to determine whether the
|
|
|
|
// preference is for a logged in user or an anonymous user. Since new users are known to have
|
|
|
|
// had their user preferences initialized in `Hooks::onLocalUserCreated()`, that means all
|
2021-09-09 22:13:48 +00:00
|
|
|
// subsequent requests to `User->getOption()` that do not have a preference set are either
|
|
|
|
// existing accounts or anonymous users. Login state makes the distinction.
|
|
|
|
$skin = $this->userOptionsLookup->getOption(
|
|
|
|
$this->user,
|
|
|
|
Constants::PREF_KEY_SKIN
|
|
|
|
);
|
|
|
|
|
|
|
|
if ( $skin === Constants::SKIN_NAME_MODERN ) {
|
|
|
|
return Constants::SKIN_VERSION_LATEST;
|
|
|
|
}
|
|
|
|
|
|
|
|
$skinVersionPref = $this->userOptionsLookup->getOption(
|
|
|
|
$this->user,
|
|
|
|
Constants::PREF_KEY_SKIN_VERSION,
|
|
|
|
$this->config->get(
|
|
|
|
$this->user->isRegistered()
|
|
|
|
? Constants::CONFIG_KEY_DEFAULT_SKIN_VERSION_FOR_EXISTING_ACCOUNTS
|
|
|
|
: Constants::CONFIG_KEY_DEFAULT_SKIN_VERSION
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2022-01-18 22:44:19 +00:00
|
|
|
// If we are in migration mode...
|
|
|
|
if ( $migrationMode ) {
|
|
|
|
// ... we must check the skin version preference for logged in users.
|
|
|
|
// No need to check for anons as wgDefaultSkin has already been consulted at this point.
|
2021-09-09 22:13:48 +00:00
|
|
|
if (
|
2022-01-18 22:44:19 +00:00
|
|
|
$this->user->isRegistered() &&
|
2021-09-09 22:13:48 +00:00
|
|
|
$skin === Constants::SKIN_NAME_LEGACY &&
|
|
|
|
$skinVersionPref === Constants::SKIN_VERSION_LATEST
|
|
|
|
) {
|
|
|
|
return Constants::SKIN_VERSION_LATEST;
|
|
|
|
}
|
|
|
|
return Constants::SKIN_VERSION_LEGACY;
|
|
|
|
}
|
2020-04-28 21:02:15 +00:00
|
|
|
return (string)$this->request->getVal(
|
|
|
|
Constants::QUERY_PARAM_SKIN_VERSION,
|
2021-09-09 22:13:48 +00:00
|
|
|
$skinVersionPref
|
2020-04-28 21:02:15 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|