<exclude name="MediaWiki.Commenting.FunctionComment.WrongStyle" />
<exclude name="MediaWiki.Commenting.IllegalSingleLineComment.IllegalSingleLineCommentStart" />
<exclude name="MediaWiki.Commenting.IllegalSingleLineComment.IllegalSingleLineCommentEnd" />
- <exclude name="MediaWiki.Commenting.LicenseComment.InvalidLicenseTag" />
<exclude name="MediaWiki.ControlStructures.AssignmentInControlStructures.AssignmentInControlStructures" />
<exclude name="MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName" />
<exclude name="MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.NewLineComment" />
| will appear. It is common in this case to use w as the folder name and |
| /wiki/ as the virtual article path where your articles pretend to be. |
| |
- | See: https://www.mediawiki.org/wiki/Manual:Short_URL |
+ | See: https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Short_URL |
+--------------------------------------------------------------------------+
Hop into your browser and surf into the wiki directory. It'll direct you into
* (T112474) Generalized the ResourceLoader mechanism for overriding modules
using a particular page during edit previews.
* Added 'ApiParseMakeOutputPage' hook.
-* (T174313) Added checkbox on Special:ListUsers to display only users in temporary
- user groups.
+* (T174313) Added checkbox on Special:ListUsers to display only users in
+ temporary user groups.
=== External library changes in 1.32 ===
* …
* mw.util.updateTooltipAccessKeys(), deprecated in 1.24, was removed. Use
jquery.accessKeyLabel instead.
* The SqlDataUpdate class, deprecated in 1.28, has been removed.
-* The Html5Internal and Html5Depurate tidy driver classes were removed, along with the
- Balancer tidy implementation. Both implementations were experimental, and were replaced
- by RemexHtml.
+* The Html5Internal and Html5Depurate tidy driver classes were removed, along
+ with the Balancer tidy implementation. Both implementations were experimental,
+ and were replaced by RemexHtml.
* (T179624) Job::insert() and ::batchInsert(), deprecated in 1.21, were both
removed. Use JobQueueGroup::singleton()->push() instead.
* The jquery.footHovzer module, for mediawiki.debug, was removed.
* The es5-shim module, empty and deprecated since 1.29, was removed.
-* The mediawiki.widgets.visibleByteLimit module, deprecated in 1.32, was removed.
- Use mediawiki.widgets.visibleLengthLimit instead.
+* The mediawiki.widgets.visibleByteLimit module alias, deprecated in 1.32, was
+ removed. Use mediawiki.widgets.visibleLengthLimit instead.
* The jquery.farbtastic module, unused since 1.18, was removed.
=== Deprecations in 1.32 ===
mediawiki.api.messages, and mediawiki.api.rollback.
* ApiBase::truncateArray() is deprecated. No replacement, as nothing is known
to use it.
+* WatchAction::getUnwatchToken is deprecated. Use WatchAction::getWatchToken
+ with the 'unwatch' action parameter instead.
=== Other changes in 1.32 ===
* Soft hyphens (U+00AD) are now automatically removed from titles; these
"jakub-onderka/php-parallel-lint": "0.9.2",
"jetbrains/phpstorm-stubs": "dev-master#1b9906084d6635456fcf3f3a01f0d7d5b99a578a",
"justinrainbow/json-schema": "~5.2",
- "mediawiki/mediawiki-codesniffer": "17.0.0",
+ "mediawiki/mediawiki-codesniffer": "18.0.0",
"monolog/monolog": "~1.22.1",
"nikic/php-parser": "3.1.3",
"nmred/kafka-php": "0.1.5",
* Internal use only. Use OutputPage::addModules() if possible.
*
* @param string $file URL to file (absolute path, protocol-relative, or full url)
- * @param string $version Style version of the file. Defaults to $wgStyleVersion
+ * @param string $unused Previously used to change the cache-busting query parameter
*/
- public function addScriptFile( $file, $version = null ) {
+ public function addScriptFile( $file, $unused = null ) {
if ( substr( $file, 0, 1 ) !== '/' && !preg_match( '#^[a-z]*://#i', $file ) ) {
// This is not an absolute path, protocol-relative url, or full scheme url,
// presumed to be an old call intended to include a file from /w/skins/common,
wfDeprecated( __METHOD__, '1.24' );
return;
}
- $path = $file;
- if ( is_null( $version ) ) {
- $version = $this->getConfig()->get( 'StyleVersion' );
- }
- $this->addScript( Html::linkedScript( wfAppendQuery( $path, $version ), $this->getCSPNonce() ) );
+ $this->addScript( Html::linkedScript( $file, $this->getCSPNonce() ) );
}
/**
$url = $style;
} else {
$config = $this->getConfig();
- $url = $config->get( 'StylePath' ) . '/' . $style . '?' .
- $config->get( 'StyleVersion' );
+ // Append file hash as query parameter
+ $url = self::transformResourcePath(
+ $config,
+ $config->get( 'StylePath' ) . '/' . $style
+ );
}
$link = Html::linkedStyle( $url, $media );
require_once "$IP/includes/compat/normal/UtfNormalUtil.php";
-$ps_validation = Profiler::instance()->scopedProfileIn( $fname . '-validation' );
-
// T48998: Bail out early if $wgArticlePath is non-absolute
foreach ( [ 'wgArticlePath', 'wgVariantArticlePath' ] as $varName ) {
if ( $$varName && !preg_match( '/^(https?:\/\/|\/)/', $$varName ) ) {
}
}
-Profiler::instance()->scopedProfileOut( $ps_validation );
-
$ps_default2 = Profiler::instance()->scopedProfileIn( $fname . '-defaults2' );
if ( $wgCanonicalServer === false ) {
Profiler::instance()->scopedProfileOut( $ps_default2 );
-$ps_misc = Profiler::instance()->scopedProfileIn( $fname . '-misc1' );
+$ps_misc = Profiler::instance()->scopedProfileIn( $fname . '-misc' );
// Raise the memory limit if it's too low
wfMemoryLimit();
wfDebug( $debug );
}
-Profiler::instance()->scopedProfileOut( $ps_misc );
-$ps_memcached = Profiler::instance()->scopedProfileIn( $fname . '-memcached' );
-
$wgMemc = wfGetMainCache();
$messageMemc = wfGetMessageCacheStorage();
', session: ' . get_class( ObjectCache::getInstance( $wgSessionCacheType ) )
);
-Profiler::instance()->scopedProfileOut( $ps_memcached );
+Profiler::instance()->scopedProfileOut( $ps_misc );
// Most of the config is out, some might want to run hooks here.
Hooks::run( 'SetupAfterCache' );
], '$wgAuth is ' . get_class( $wgAuth ) );
}
-// Set up the session
-$ps_session = Profiler::instance()->scopedProfileIn( $fname . '-session' );
/**
* @var MediaWiki\Session\SessionId|null $wgInitialSessionId The persistent
* session ID (if any) loaded at startup
);
}
}
-Profiler::instance()->scopedProfileOut( $ps_session );
/**
* @var User $wgUser
// of the extension file. This allows the extension to perform
// any necessary initialisation in the fully initialised environment
foreach ( $wgExtensionFunctions as $func ) {
- // Allow closures in PHP 5.3+
- if ( is_object( $func ) && $func instanceof Closure ) {
- $profName = $fname . '-extensions-closure';
- } elseif ( is_array( $func ) ) {
- if ( is_object( $func[0] ) ) {
- $profName = $fname . '-extensions-' . get_class( $func[0] ) . '::' . $func[1];
- } else {
- $profName = $fname . '-extensions-' . implode( '::', $func );
- }
- } else {
- $profName = $fname . '-extensions-' . strval( $func );
- }
-
- $ps_ext_func = Profiler::instance()->scopedProfileIn( $profName );
call_user_func( $func );
- Profiler::instance()->scopedProfileOut( $ps_ext_func );
}
// If the session user has a 0 id but a valid name, that means we need to
if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) {
$sessionUser = MediaWiki\Session\SessionManager::getGlobalSession()->getUser();
if ( $sessionUser->getId() === 0 && User::isValidUserName( $sessionUser->getName() ) ) {
- $ps_autocreate = Profiler::instance()->scopedProfileIn( $fname . '-autocreate' );
$res = MediaWiki\Auth\AuthManager::singleton()->autoCreateUser(
$sessionUser,
MediaWiki\Auth\AuthManager::AUTOCREATE_SOURCE_SESSION,
true
);
- Profiler::instance()->scopedProfileOut( $ps_autocreate );
\MediaWiki\Logger\LoggerFactory::getInstance( 'authevents' )->info( 'Autocreation attempt', [
'event' => 'autocreate',
'status' => $res,
*
* If you don't want to do anything with the form, just return false here.
*
+ * This method will be passed to the HTMLForm as a submit callback (see
+ * HTMLForm::setSubmitCallback) and must return as documented for HTMLForm::trySubmit.
+ *
+ * @see HTMLForm::setSubmitCallback()
+ * @see HTMLForm::trySubmit()
* @param array $data
- * @return bool|array True for success, false for didn't-try, array of errors on failure
+ * @return bool|string|array|Status Must return as documented for HTMLForm::trySubmit
*/
abstract public function onSubmit( $data );
}
public function onSubmit( $data ) {
- self::doWatch( $this->getTitle(), $this->getUser() );
-
- return true;
+ return self::doWatch( $this->getTitle(), $this->getUser() );
}
protected function checkCanExecute( User $user ) {
* @param string $action Optionally override the action to 'watch'
* @return string Token
* @since 1.18
+ * @deprecated since 1.32 Use WatchAction::getWatchToken() with action 'unwatch' directly.
*/
public static function getUnwatchToken( Title $title, User $user, $action = 'unwatch' ) {
+ wfDeprecated( __METHOD__, '1.32' );
return self::getWatchToken( $title, $user, $action );
}
* http://www.gnu.org/copyleft/gpl.html
*
* @file
- * @license GNU GPL v2 or later
+ * @license GPL-2.0-or-later
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
*/
require_once __DIR__ . '/../AutoLoader.php';
/**
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
*/
class ComposerHookHandler {
use Composer\Semver\Constraint\Constraint;
/**
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
*/
class ComposerPackageModifier {
<?php
/**
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
*/
class ComposerVersionNormalizer {
* @file
* @ingroup Database
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Daniel Kinzler
*/
abstract class DBAccessBase implements IDBAccessObject {
* @since 1.29
* @ingroup InterwikiLookup
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
*/
use Interwiki;
* @version 0.1.1 -- 2010-09-11
* @author Trevor Parscal <tparscal@wikimedia.org>
* @copyright Copyright 2010 Wikimedia Foundation
- * @license http://www.apache.org/licenses/LICENSE-2.0
+ * @license Apache-2.0
*/
/**
*
* @file
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
*/
abstract class GenericArrayObject extends ArrayObject {
}
if ( self::isIPv4( $ip ) ) {
// Remove leading 0's from octet representation of IPv4 address
- $ip = preg_replace( '/(?:^|(?<=\.))0+(?=[1-9]|0\.|0$)/', '', $ip );
+ $ip = preg_replace( '!(?:^|(?<=\.))0+(?=[1-9]|0[./]|0$)!', '', $ip );
return $ip;
}
// Remove any whitespaces, convert to upper case
*
* @file
* @author Paul Copperman <paul.copperman@gmail.com>
- * @license Choose any of Apache, MIT, GPL, LGPL
+ * @license Apache-2.0
+ * @license MIT
+ * @license GPL-2.0-or-later
+ * @license LGPL-2.1-or-later
*/
/**
* http://www.gnu.org/copyleft/gpl.html
*
* @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
* @since 1.25
*/
*
* @file
* @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
* @since 1.22
*/
* http://www.gnu.org/copyleft/gpl.html
*
* @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
* @since 1.27
*/
*
* @file
* @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
* @since 1.19
*/
*
* @file
* @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
* @since 1.19
*/
use MediaWiki\Linker\LinkRenderer;
* http://www.gnu.org/copyleft/gpl.html
*
* @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
* @since 1.25
*/
*
* @file
* @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
* @since 1.22
*/
*
* @file
* @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
* @since 1.22
*/
*
* @file
* @author Kunal Grover
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
* @since 1.24
*/
*
* @file
* @author Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
* @since 1.22
*/
* http://www.gnu.org/copyleft/gpl.html
*
* @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
* @since 1.26
*/
*
* @file
* @author Alexandre Emsenhuber
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
* @since 1.22
*/
* http://www.gnu.org/copyleft/gpl.html
*
* @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
* @since 1.25
*/
* http://www.gnu.org/copyleft/gpl.html
*
* @file
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
*/
/**
* @ingroup Media
* @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
* @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason, 2009 Brent Garber
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @license GPL-2.0-or-later
* @see http://exif.org/Exif2-2.PDF The Exif 2.2 specification
* @file
*/
* @ingroup Media
* @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
* @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason, 2009 Brent Garber, 2010 Brian Wolff
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @license GPL-2.0-or-later
* @see http://exif.org/Exif2-2.PDF The Exif 2.2 specification
* @file
*/
* @author "Derk-Jan Hartman <hartman _at_ videolan d0t org>"
* @author Brion Vibber
* @copyright Copyright © 2010-2010 Brion Vibber, Derk-Jan Hartman
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @license GPL-2.0-or-later
*/
/**
* @file
* @ingroup Site
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
* @author Katie Filbert < aude.wiki@gmail.com >
*/
* @file
* @ingroup Site
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
* @author Daniel Kinzler
*/
*
* @file
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
*/
/**
*
* @since 1.27
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author John Erling Blad < jeblad@gmail.com >
* @author Daniel Kinzler
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
*
* @file
* @ingroup Site
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author John Erling Blad < jeblad@gmail.com >
* @author Daniel Kinzler
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
* @file
* @ingroup Site
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
*/
class Site implements Serializable {
* @file
* @ingroup Site
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Daniel Kinzler
*/
class SiteExporter {
* @file
* @ingroup Site
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Daniel Kinzler
*/
class SiteImporter {
* @file
* @ingroup Site
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
*/
class SiteList extends GenericArrayObject {
* @file
* @ingroup Site
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
*/
interface SiteLookup {
* @file
* @ingroup Site
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Daniel Kinzler
*/
class SiteSQLStore {
* @file
* @ingroup Site
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
*/
interface SiteStore extends SiteLookup {
*
* @file
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
*/
class SitesCacheFileBuilder {
* @ingroup SpecialPage
* @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
* @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
*/
/**
* @file
* @ingroup Watchlist
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
*/
class WatchedItemQueryService {
* @file
* @ingroup Watchlist
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
*/
interface WatchedItemQueryServiceExtension {
* Select and input widget.
*
* @copyright 2011-2018 MediaWiki Widgets Team and others; see AUTHORS.txt
- * @license The MIT License (MIT); see LICENSE.txt
+ * @license MIT
*/
class SizeFilterWidget extends \OOUI\Widget {
*
* @file
* @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
- * @license http://www.gnu.org/copyleft/fdl.html GNU Free Documentation License
+ * @license GPL-2.0-or-later
+ * @license GFDL-1.3-or-later
* @ingroup Language
*/
/**
* @copyright Copyright © 2006, Niklas Laxström
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
*/
$linkTrail = '/^([a-zA-ZĀāČčĒēĢģĪīĶķĻļŅņŠšŪūŽž]+)(.*)$/sDu';
*/
/**
- * @license http://www.gnu.org/copyleft/fdl.html GNU Free Documentation License
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ * @license GFDL-1.3-or-later
+ * @license GPL-2.0-or-later
*
* @see https://meta.wikimedia.org/w/index.php?title=LanguageNn.php&action=history
* @see https://nn.wikipedia.org/w/index.php?title=Brukar:Dittaeva/LanguageNn.php&action=history
*
* @since 1.29
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Florian Schmidt
*/
class AddSite extends Maintenance {
$this->addOption( 'dry-run', 'Print debug info instead of actually deleting' );
$this->addOption(
'check-old',
- 'Check old patrol logs (for deleting old format autopatrols).' .
- 'Note that this will not delete rows older than 2011 (MediaWiki 1.18).'
+ 'Check old patrol logs (for deleting old format autopatrols).'
);
$this->addOption(
'before',
$autopatrols = [];
foreach ( $result as $row ) {
$last = $row->log_id;
- Wikimedia\suppressWarnings();
- $params = unserialize( $row->log_params );
- Wikimedia\restoreWarnings();
+ $logEntry = DatabaseLogEntry::newFromRow( $row );
+ $params = $logEntry->getParameters();
+ if ( !is_array( $params ) ) {
+ continue;
+ }
- // Skipping really old rows, before 2011
- if ( !is_array( $params ) || !array_key_exists( '6::auto', $params ) ) {
+ // This logic belongs to PatrolLogFormatter::getMessageKey
+ // and LogFormatter::extractParameters the 'auto' value is logically presented as key [5].
+ // For legacy case the logical key is index + 3, meaning [2].
+ // For the modern case, the logical key is index - 1 meaning [6].
+ if ( array_key_exists( '6::auto', $params ) ) {
+ // Between 2011-2016 autopatrol logs
+ $auto = $params['6::auto'] === true;
+ } elseif ( $logEntry->isLegacy() === true && array_key_exists( 2, $params ) ) {
+ // Pre-2011 autopatrol logs
+ $auto = $params[2] === '1';
+ } else {
continue;
}
- $auto = $params['6::auto'];
- if ( $auto ) {
+ if ( $auto === true ) {
$autopatrols[] = $row->log_id;
}
}
*
* @since 1.25
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Daniel Kinzler
*/
class ExportSites extends Maintenance {
*
* @since 1.25
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Daniel Kinzler
*/
class ImportSites extends Maintenance {
* @file
* @ingroup Maintenance
* @author Antoine Musso <hashar at free dot fr>
- * @license GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
*/
require_once __DIR__ . '/Maintenance.php';
* @file
* @ingroup Maintenance
* @author Rob Church <robchur@gmail.com>
- * @license GNU General Public Licence 2.0 or later
+ * @license GPL-2.0-or-later
*/
use Wikimedia\Rdbms\IDatabase;
* @author Brion Vibber
* @author Rob Church <robchur@gmail.com>
*
- * @license GNU General Public License 2.0 or later
+ * @license GPL-2.0-or-later
*/
require_once __DIR__ . '/Maintenance.php';
print '<?xml version="1.0"?>';
print Xml::openElement( 'OpenSearchDescription',
[
- 'xmlns' => 'http://a9.com/-/spec/opensearch/1.1/',
- 'xmlns:moz' => 'http://www.mozilla.org/2006/browser/search/' ] );
+ 'xmlns' => 'http://www.opensearch.org/Specifications/OpenSearch/1.1',
+ 'xmlns:moz' => 'https://www.mozilla.org/2006/browser/search/' ] );
/* The spec says the ShortName must be no longer than 16 characters,
* but 16 is *realllly* short. In practice, browsers don't appear to care
* @group Action
* @group Database
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Thiemo Kreuz
*/
class ActionTest extends MediaWikiTestCase {
--- /dev/null
+<?php
+
+/**
+ * @covers WatchAction
+ *
+ * @group Action
+ */
+class WatchActionTest extends MediaWikiTestCase {
+
+ /**
+ * @var WatchAction
+ */
+ private $watchAction;
+
+ /**
+ * @var WikiPage
+ */
+ private $testWikiPage;
+
+ protected function setUp() {
+ parent::setUp();
+
+ $testTitle = Title::newFromText( 'UTTest' );
+ $this->testWikiPage = new WikiPage( $testTitle );
+ $testContext = new DerivativeContext( RequestContext::getMain() );
+ $testContext->setTitle( $testTitle );
+ $this->watchAction = new WatchAction( $this->testWikiPage, $testContext );
+ }
+
+ /**
+ * @throws MWException
+ */
+ protected function tearDown() {
+ parent::tearDown();
+
+ Hooks::clear( 'WatchArticle' );
+ Hooks::clear( 'UnwatchArticle' );
+ }
+
+ /**
+ * @covers WatchAction::getName()
+ */
+ public function testGetName() {
+ $this->assertEquals( 'watch', $this->watchAction->getName() );
+ }
+
+ /**
+ * @covers WatchAction::requiresUnblock()
+ */
+ public function testRequiresUnlock() {
+ $this->assertFalse( $this->watchAction->requiresUnblock() );
+ }
+
+ /**
+ * @covers WatchAction::doesWrites()
+ */
+ public function testDoesWrites() {
+ $this->assertTrue( $this->watchAction->doesWrites() );
+ }
+
+ /**
+ * @covers WatchAction::onSubmit()
+ * @covers WatchAction::doWatch()
+ */
+ public function testOnSubmit() {
+ /** @var Status $actual */
+ $actual = $this->watchAction->onSubmit( [] );
+
+ $this->assertTrue( $actual->isGood() );
+ }
+
+ /**
+ * @covers WatchAction::onSubmit()
+ * @covers WatchAction::doWatch()
+ */
+ public function testOnSubmitHookAborted() {
+ Hooks::register( 'WatchArticle', function () {
+ return false;
+ } );
+
+ /** @var Status $actual */
+ $actual = $this->watchAction->onSubmit( [] );
+
+ $this->assertInstanceOf( Status::class, $actual );
+ $this->assertTrue( $actual->hasMessage( 'hookaborted' ) );
+ }
+
+ /**
+ * @covers WatchAction::checkCanExecute()
+ */
+ public function testShowUserNotLoggedIn() {
+ $notLoggedInUser = new User();
+ $testContext = new DerivativeContext( $this->watchAction->getContext() );
+ $testContext->setUser( $notLoggedInUser );
+ $watchAction = new WatchAction( $this->testWikiPage, $testContext );
+ $this->setExpectedException( UserNotLoggedIn::class );
+
+ $watchAction->show();
+ }
+
+ /**
+ * @covers WatchAction::checkCanExecute()
+ */
+ public function testShowUserLoggedInNoException() {
+ $loggedInUser = $this->getMock( User::class );
+ $loggedInUser->method( 'isLoggedIn' )->willReturn( true );
+ $testContext = new DerivativeContext( $this->watchAction->getContext() );
+ $testContext->setUser( $loggedInUser );
+ $watchAction = new WatchAction( $this->testWikiPage, $testContext );
+
+ $exception = null;
+ try {
+ $watchAction->show();
+ } catch ( UserNotLoggedIn $e ) {
+ $exception = $e;
+ }
+ $this->assertNull( $exception,
+ 'UserNotLoggedIn exception should not be thrown if user is logged in.' );
+ }
+
+ /**
+ * @covers WatchAction::onSuccess()
+ */
+ public function testOnSuccessMainNamespaceTitle() {
+ $testContext = $this->getMock(
+ DerivativeContext::class,
+ [ 'msg' ],
+ [ $this->watchAction->getContext() ]
+ );
+ $testOutput = new OutputPage( $testContext );
+ $testContext->setOutput( $testOutput );
+ $testContext->method( 'msg' )->willReturnCallback( function ( $msgKey ) {
+ return new RawMessage( $msgKey );
+ } );
+ $watchAction = new WatchAction( $this->testWikiPage, $testContext );
+
+ $watchAction->onSuccess();
+
+ $this->assertEquals( '<p>addedwatchtext
+</p>', $testOutput->getHTML() );
+ }
+
+ /**
+ * @covers WatchAction::onSuccess()
+ */
+ public function testOnSuccessTalkPage() {
+ $testContext = $this->getMock(
+ DerivativeContext::class,
+ [],
+ [ $this->watchAction->getContext() ]
+ );
+ $testOutput = new OutputPage( $testContext );
+ $testContext->method( 'getOutput' )->willReturn( $testOutput );
+ $testContext->method( 'msg' )->willReturnCallback( function ( $msgKey ) {
+ return new RawMessage( $msgKey );
+ } );
+ $talkPageTitle = Title::newFromText( 'Talk:UTTest' );
+ $testContext->setTitle( $talkPageTitle );
+ $watchAction = new WatchAction( new WikiPage( $talkPageTitle ), $testContext );
+
+ $watchAction->onSuccess();
+
+ $this->assertEquals( '<p>addedwatchtext-talk
+</p>', $testOutput->getHTML() );
+ }
+
+ /**
+ * @covers WatchAction::doWatch()
+ */
+ public function testDoWatchNoCheckRights() {
+ $notPermittedUser = $this->getMock( User::class );
+ $notPermittedUser->method( 'isAllowed' )->willReturn( false );
+
+ $actual = WatchAction::doWatch( $this->testWikiPage->getTitle(), $notPermittedUser, false );
+
+ $this->assertTrue( $actual->isGood() );
+ }
+
+ /**
+ * @covers WatchAction::doWatch()
+ */
+ public function testDoWatchUserNotPermittedStatusNotGood() {
+ $notPermittedUser = $this->getMock( User::class );
+ $notPermittedUser->method( 'isAllowed' )->willReturn( false );
+
+ $actual = WatchAction::doWatch( $this->testWikiPage->getTitle(), $notPermittedUser, true );
+
+ $this->assertFalse( $actual->isGood() );
+ }
+
+ /**
+ * @covers WatchAction::doWatch()
+ */
+ public function testDoWatchCallsUserAddWatch() {
+ $permittedUser = $this->getMock( User::class );
+ $permittedUser->method( 'isAllowed' )->willReturn( true );
+ $permittedUser->expects( $this->once() )
+ ->method( 'addWatch' )
+ ->with( $this->equalTo( $this->testWikiPage->getTitle() ), $this->equalTo( true ) );
+
+ $actual = WatchAction::doWatch( $this->testWikiPage->getTitle(), $permittedUser );
+
+ $this->assertTrue( $actual->isGood() );
+ }
+
+ /**
+ * @covers WatchAction::doUnWatch()
+ */
+ public function testDoUnWatchWithoutRights() {
+ $notPermittedUser = $this->getMock( User::class );
+ $notPermittedUser->method( 'isAllowed' )->willReturn( false );
+
+ $actual = WatchAction::doUnWatch( $this->testWikiPage->getTitle(), $notPermittedUser );
+
+ $this->assertFalse( $actual->isGood() );
+ }
+
+ /**
+ * @covers WatchAction::doUnWatch()
+ */
+ public function testDoUnWatchUserHookAborted() {
+ $permittedUser = $this->getMock( User::class );
+ $permittedUser->method( 'isAllowed' )->willReturn( true );
+ Hooks::register( 'UnwatchArticle', function () {
+ return false;
+ } );
+
+ $status = WatchAction::doUnWatch( $this->testWikiPage->getTitle(), $permittedUser );
+
+ $this->assertFalse( $status->isGood() );
+ $errors = $status->getErrors();
+ $this->assertEquals( 1, count( $errors ) );
+ $this->assertEquals( 'hookaborted', $errors[0]['message'] );
+ }
+
+ /**
+ * @covers WatchAction::doUnWatch()
+ */
+ public function testDoUnWatchCallsUserRemoveWatch() {
+ $permittedUser = $this->getMock( User::class );
+ $permittedUser->method( 'isAllowed' )->willReturn( true );
+ $permittedUser->expects( $this->once() )
+ ->method( 'removeWatch' )
+ ->with( $this->equalTo( $this->testWikiPage->getTitle() ) );
+
+ $actual = WatchAction::doUnWatch( $this->testWikiPage->getTitle(), $permittedUser );
+
+ $this->assertTrue( $actual->isGood() );
+ }
+
+ /**
+ * @covers WatchAction::getWatchToken()
+ */
+ public function testGetWatchTokenNormalizesToWatch() {
+ $user = $this->getMock( User::class );
+ $user->expects( $this->once() )
+ ->method( 'getEditToken' )
+ ->with( $this->equalTo( 'watch' ) );
+
+ WatchAction::getWatchToken( $this->watchAction->getTitle(), $user, 'INVALID_ACTION' );
+ }
+
+ /**
+ * @covers WatchAction::getWatchToken()
+ */
+ public function testGetWatchTokenProxiesUserGetEditToken() {
+ $user = $this->getMock( User::class );
+ $user->expects( $this->once() )->method( 'getEditToken' );
+
+ WatchAction::getWatchToken( $this->watchAction->getTitle(), $user );
+ }
+
+ /**
+ * @covers WatchAction::getUnwatchToken()
+ */
+ public function testGetUnwatchToken() {
+ $user = $this->getMock( User::class );
+ $user->expects( $this->once() )->method( 'getEditToken' );
+ $this->hideDeprecated( 'WatchAction::getUnwatchToken' );
+
+ WatchAction::getUnWatchToken( $this->watchAction->getTitle(), $user );
+ }
+
+ /**
+ * @covers WatchAction::doWatchOrUnwatch()
+ */
+ public function testDoWatchOrUnwatchUserNotLoggedIn() {
+ $user = $this->getLoggedInIsWatchedUser( false );
+ $user->expects( $this->never() )->method( 'removeWatch' );
+ $user->expects( $this->never() )->method( 'addWatch' );
+
+ $status = WatchAction::doWatchOrUnwatch( true, $this->watchAction->getTitle(), $user );
+
+ $this->assertTrue( $status->isGood() );
+ }
+
+ /**
+ * @covers WatchAction::doWatchOrUnwatch()
+ */
+ public function testDoWatchOrUnwatchSkipsIfAlreadyWatched() {
+ $user = $this->getLoggedInIsWatchedUser();
+ $user->expects( $this->never() )->method( 'removeWatch' );
+ $user->expects( $this->never() )->method( 'addWatch' );
+
+ $status = WatchAction::doWatchOrUnwatch( true, $this->watchAction->getTitle(), $user );
+
+ $this->assertTrue( $status->isGood() );
+ }
+
+ /**
+ * @covers WatchAction::doWatchOrUnwatch()
+ */
+ public function testDoWatchOrUnwatchSkipsIfAlreadyUnWatched() {
+ $user = $this->getLoggedInIsWatchedUser( true, false );
+ $user->expects( $this->never() )->method( 'removeWatch' );
+ $user->expects( $this->never() )->method( 'addWatch' );
+
+ $status = WatchAction::doWatchOrUnwatch( false, $this->watchAction->getTitle(), $user );
+
+ $this->assertTrue( $status->isGood() );
+ }
+
+ /**
+ * @covers WatchAction::doWatchOrUnwatch()
+ */
+ public function testDoWatchOrUnwatchWatchesIfWatch() {
+ $user = $this->getLoggedInIsWatchedUser( true, false );
+ $user->expects( $this->never() )->method( 'removeWatch' );
+ $user->expects( $this->once() )
+ ->method( 'addWatch' )
+ ->with( $this->equalTo( $this->testWikiPage->getTitle() ), $this->equalTo( false ) );
+
+ $status = WatchAction::doWatchOrUnwatch( true, $this->watchAction->getTitle(), $user );
+
+ $this->assertTrue( $status->isGood() );
+ }
+
+ /**
+ * @covers WatchAction::doWatchOrUnwatch()
+ */
+ public function testDoWatchOrUnwatchUnwatchesIfUnwatch() {
+ $user = $this->getLoggedInIsWatchedUser();
+ $user->method( 'isAllowed' )->willReturn( true );
+ $user->expects( $this->never() )->method( 'addWatch' );
+ $user->expects( $this->once() )
+ ->method( 'removeWatch' )
+ ->with( $this->equalTo( $this->testWikiPage->getTitle() ) );
+
+ $status = WatchAction::doWatchOrUnwatch( false, $this->watchAction->getTitle(), $user );
+
+ $this->assertTrue( $status->isGood() );
+ }
+
+ /**
+ * @param bool $isLoggedIn Whether the user should be "marked" as logged in
+ * @param bool $isWatched The value any call to isWatched should return
+ * @return PHPUnit_Framework_MockObject_MockObject
+ */
+ private function getLoggedInIsWatchedUser( $isLoggedIn = true, $isWatched = true ) {
+ $user = $this->getMock( User::class );
+ $user->method( 'isLoggedIn' )->willReturn( $isLoggedIn );
+ $user->method( 'isWatched' )->willReturn( $isWatched );
+
+ return $user;
+ }
+
+}
/**
* @covers HTMLForm
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Gergő Tisza
* @author Thiemo Mättig
*/
*
* @group JobQueue
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Thiemo Kreuz
*/
class JobQueueMemoryTest extends PHPUnit\Framework\TestCase {
* @group JobQueue
* @group Database
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Addshore
*/
class CategoryMembershipChangeJobTest extends MediaWikiTestCase {
* @group JobQueue
* @group Database
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Addshore
*/
class ClearUserWatchlistJobTest extends MediaWikiTestCase {
[ '0.0.0.0', '0.0.0.0' ],
[ '0.0.0.0', '00.00.00.00' ],
[ '0.0.0.0', '000.000.000.000' ],
+ [ '0.0.0.0/24', '000.000.000.000/24' ],
[ '141.0.11.253', '141.000.011.253' ],
[ '1.2.4.5', '1.2.4.5' ],
[ '1.2.4.5', '01.02.04.05' ],
<?php
/**
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Addshore
*
* @covers SpecialBlankpage
*
* @since 1.26
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
* @author Daniel Kinzler
* @author Addshore
*
* @since 1.30
*
- * @license GNU GPL v2+
+ * @license GPL-2.0-or-later
*/
class SpecialShortpagesTest extends MediaWikiTestCase {
'log_timestamp' => 20091223210426
];
+ // Autopatrol #4 very old way
+ $logs[] = [
+ 'log_type' => 'patrol',
+ 'log_action' => 'patrol',
+ 'log_user' => 7257,
+ 'log_params' => "9227851\n0\n1",
+ 'log_timestamp' => 20081223210426
+ ];
+
+ // Manual patrol #3 very old way
+ $logs[] = [
+ 'log_type' => 'patrol',
+ 'log_action' => 'patrol',
+ 'log_user' => 7258,
+ 'log_params' => "9227851\n0\n0",
+ 'log_timestamp' => 20091223210426
+ ];
+
wfGetDB( DB_MASTER )->insert( 'logging', $logs );
}
'log_action' => 'patrol',
'log_user' => '7256',
],
+ (object)[
+ 'log_type' => 'patrol',
+ 'log_action' => 'patrol',
+ 'log_user' => '7257',
+ ],
+ (object)[
+ 'log_type' => 'patrol',
+ 'log_action' => 'patrol',
+ 'log_user' => '7258',
+ ],
];
$cases = [
$allRows[3],
$allRows[5],
$allRows[6],
+ $allRows[7],
+ $allRows[8],
],
[ '--sleep', '0', '-q' ]
],
$allRows[4],
$allRows[5],
$allRows[6],
+ $allRows[7],
+ $allRows[8],
],
[ '--sleep', '0', '--before', '20060123210426', '-q' ]
],
$allRows[3],
$allRows[4],
$allRows[6],
+ $allRows[8],
],
[ '--sleep', '0', '--check-old', '-q' ]
],