From: Aryeh Gregor Date: Tue, 24 Jul 2018 16:44:09 +0000 (+0300) Subject: MagicWordFactory to replace MagicWord static members/methods X-Git-Tag: 1.34.0-rc.0~4621^2 X-Git-Url: http://git.cyclocoop.org/%7B%24www_url%7Dadmin/%24spUrl?a=commitdiff_plain;h=5189333c3915e08fb5676be637b9c0fb588d1823;p=lhc%2Fweb%2Fwiklou.git MagicWordFactory to replace MagicWord static members/methods Static members of MagicWord have been removed. Static methods are soft-deprecated and forward to the factory. They will be hard-deprecated when all callers are removed from core. MagicWord::clearCache() has been removed. Instead, call resetServiceForTesting( 'MagicWordFactory' ) on your MediaWikiServices object. Change-Id: Ie061fe90f9b9eca0cbf7e8199d9ca325c464867a Bug: T200247 --- diff --git a/RELEASE-NOTES-1.32 b/RELEASE-NOTES-1.32 index bbcd6c2727..c5e9a6715e 100644 --- a/RELEASE-NOTES-1.32 +++ b/RELEASE-NOTES-1.32 @@ -209,6 +209,11 @@ because of Phabricator reports. * getItemsData: Use getItems instead and get the data property * Two OutputPage methods, addMetadataLink() and getMetadataAttribute(), were removed. Use addLink() instead. +* All MagicWord static member variables have been removed. Use appropriate + hooks or MagicWordFactory methods instead. +* MagicWord::clearCache() has been removed. Instead, create a new + MagicWordFactory, such as by calling + resetServiceForTesting( 'MagicWordFactory' ) on a MediaWikiServices. === Deprecations in 1.32 === * Use of a StartProfiler.php file is deprecated in favour of placing @@ -304,6 +309,8 @@ because of Phabricator reports. * The $wgExternalDiffEngine value 'wikidiff2' is deprecated. To use wikidiff2 just enable the PHP extension, and it will be autodetected. * The wfUseMW function, soft-deprecated in 1.26, is now hard deprecated. +* All MagicWord static methods are now deprecated. Use the MagicWordFactory + methods instead. === Other changes in 1.32 === * (T198811) The following tables have had their UNIQUE indexes turned into diff --git a/autoload.php b/autoload.php index 758806009b..b5b5c52060 100644 --- a/autoload.php +++ b/autoload.php @@ -832,6 +832,7 @@ $wgAutoloadLocalClasses = [ 'MachineReadableRCFeedFormatter' => __DIR__ . '/includes/rcfeed/MachineReadableRCFeedFormatter.php', 'MagicWord' => __DIR__ . '/includes/MagicWord.php', 'MagicWordArray' => __DIR__ . '/includes/MagicWordArray.php', + 'MagicWordFactory' => __DIR__ . '/includes/MagicWordFactory.php', 'MailAddress' => __DIR__ . '/includes/mail/MailAddress.php', 'MainConfigDependency' => __DIR__ . '/includes/cache/CacheDependency.php', 'MaintainableDBConnRef' => __DIR__ . '/includes/libs/rdbms/database/MaintainableDBConnRef.php', diff --git a/includes/MagicWord.php b/includes/MagicWord.php index 9cef700007..a193c9fda9 100644 --- a/includes/MagicWord.php +++ b/includes/MagicWord.php @@ -21,20 +21,18 @@ * @ingroup Parser */ +use MediaWiki\MediaWikiServices; + /** * This class encapsulates "magic words" such as "#redirect", __NOTOC__, etc. * * @par Usage: * @code - * if (MagicWord::get( 'redirect' )->match( $text ) ) { + * if ( $magicWordFactory->get( 'redirect' )->match( $text ) ) { * // some code * } * @endcode * - * Possible future improvements: - * * Simultaneous searching for a number of magic words - * * MagicWord::$mObjects in shared memory - * * Please avoid reading the data out of one of these objects and then writing * special case code. If possible, add another match()-like function here. * @@ -92,170 +90,12 @@ class MagicWord { /** @var bool */ private $mFound = false; - /** @var bool */ - public static $mVariableIDsInitialised = false; - - /** @var string[] */ - public static $mVariableIDs = [ - '!', - 'currentmonth', - 'currentmonth1', - 'currentmonthname', - 'currentmonthnamegen', - 'currentmonthabbrev', - 'currentday', - 'currentday2', - 'currentdayname', - 'currentyear', - 'currenttime', - 'currenthour', - 'localmonth', - 'localmonth1', - 'localmonthname', - 'localmonthnamegen', - 'localmonthabbrev', - 'localday', - 'localday2', - 'localdayname', - 'localyear', - 'localtime', - 'localhour', - 'numberofarticles', - 'numberoffiles', - 'numberofedits', - 'articlepath', - 'pageid', - 'sitename', - 'server', - 'servername', - 'scriptpath', - 'stylepath', - 'pagename', - 'pagenamee', - 'fullpagename', - 'fullpagenamee', - 'namespace', - 'namespacee', - 'namespacenumber', - 'currentweek', - 'currentdow', - 'localweek', - 'localdow', - 'revisionid', - 'revisionday', - 'revisionday2', - 'revisionmonth', - 'revisionmonth1', - 'revisionyear', - 'revisiontimestamp', - 'revisionuser', - 'revisionsize', - 'subpagename', - 'subpagenamee', - 'talkspace', - 'talkspacee', - 'subjectspace', - 'subjectspacee', - 'talkpagename', - 'talkpagenamee', - 'subjectpagename', - 'subjectpagenamee', - 'numberofusers', - 'numberofactiveusers', - 'numberofpages', - 'currentversion', - 'rootpagename', - 'rootpagenamee', - 'basepagename', - 'basepagenamee', - 'currenttimestamp', - 'localtimestamp', - 'directionmark', - 'contentlanguage', - 'pagelanguage', - 'numberofadmins', - 'cascadingsources', - ]; - - /** Array of caching hints for ParserCache - * @var array [ string => int ] - */ - public static $mCacheTTLs = [ - 'currentmonth' => 86400, - 'currentmonth1' => 86400, - 'currentmonthname' => 86400, - 'currentmonthnamegen' => 86400, - 'currentmonthabbrev' => 86400, - 'currentday' => 3600, - 'currentday2' => 3600, - 'currentdayname' => 3600, - 'currentyear' => 86400, - 'currenttime' => 3600, - 'currenthour' => 3600, - 'localmonth' => 86400, - 'localmonth1' => 86400, - 'localmonthname' => 86400, - 'localmonthnamegen' => 86400, - 'localmonthabbrev' => 86400, - 'localday' => 3600, - 'localday2' => 3600, - 'localdayname' => 3600, - 'localyear' => 86400, - 'localtime' => 3600, - 'localhour' => 3600, - 'numberofarticles' => 3600, - 'numberoffiles' => 3600, - 'numberofedits' => 3600, - 'currentweek' => 3600, - 'currentdow' => 3600, - 'localweek' => 3600, - 'localdow' => 3600, - 'numberofusers' => 3600, - 'numberofactiveusers' => 3600, - 'numberofpages' => 3600, - 'currentversion' => 86400, - 'currenttimestamp' => 3600, - 'localtimestamp' => 3600, - 'pagesinnamespace' => 3600, - 'numberofadmins' => 3600, - 'numberingroup' => 3600, - ]; - - /** @var string[] */ - public static $mDoubleUnderscoreIDs = [ - 'notoc', - 'nogallery', - 'forcetoc', - 'toc', - 'noeditsection', - 'newsectionlink', - 'nonewsectionlink', - 'hiddencat', - 'index', - 'noindex', - 'staticredirect', - 'notitleconvert', - 'nocontentconvert', - ]; - - /** @var string[] */ - public static $mSubstIDs = [ - 'subst', - 'safesubst', - ]; - - /** @var array [ string => MagicWord ] */ - public static $mObjects = []; - - /** @var MagicWordArray */ - public static $mDoubleUnderscoreArray = null; - /**#@-*/ /** * Create a new MagicWord object * - * Use factory instead: MagicWord::get + * Use factory instead: MagicWordFactory::get * * @param string|null $id The internal name of the magic word * @param string[]|string $syn synonyms for the magic word @@ -273,36 +113,29 @@ class MagicWord { * @param string $id The internal name of the magic word * * @return MagicWord + * @deprecated since 1.32, use MagicWordFactory::get */ - public static function &get( $id ) { - if ( !isset( self::$mObjects[$id] ) ) { - $mw = new MagicWord(); - $mw->load( $id ); - self::$mObjects[$id] = $mw; - } - return self::$mObjects[$id]; + public static function get( $id ) { + return MediaWikiServices::getInstance()->getMagicWordFactory()->get( $id ); } /** * Get an array of parser variable IDs * * @return string[] + * @deprecated since 1.32, use MagicWordFactory::getVariableIDs */ public static function getVariableIDs() { - if ( !self::$mVariableIDsInitialised ) { - # Get variable IDs - Hooks::run( 'MagicWordwgVariableIDs', [ &self::$mVariableIDs ] ); - self::$mVariableIDsInitialised = true; - } - return self::$mVariableIDs; + return MediaWikiServices::getInstance()->getMagicWordFactory()->getVariableIDs(); } /** * Get an array of parser substitution modifier IDs * @return string[] + * @deprecated since 1.32, use MagicWordFactory::getSubstIDs */ public static function getSubstIDs() { - return self::$mSubstIDs; + return MediaWikiServices::getInstance()->getMagicWordFactory()->getSubstIDs(); } /** @@ -310,34 +143,20 @@ class MagicWord { * * @param string $id * @return int + * @deprecated since 1.32, use MagicWordFactory::getCacheTTL */ public static function getCacheTTL( $id ) { - if ( array_key_exists( $id, self::$mCacheTTLs ) ) { - return self::$mCacheTTLs[$id]; - } else { - return -1; - } + return MediaWikiServices::getInstance()->getMagicWordFactory()->getCacheTTL( $id ); } /** * Get a MagicWordArray of double-underscore entities * * @return MagicWordArray + * @deprecated since 1.32, use MagicWordFactory::getDoubleUnderscoreArray */ public static function getDoubleUnderscoreArray() { - if ( is_null( self::$mDoubleUnderscoreArray ) ) { - Hooks::run( 'GetDoubleUnderscoreIDs', [ &self::$mDoubleUnderscoreIDs ] ); - self::$mDoubleUnderscoreArray = new MagicWordArray( self::$mDoubleUnderscoreIDs ); - } - return self::$mDoubleUnderscoreArray; - } - - /** - * Clear the self::$mObjects variable - * For use in parser tests - */ - public static function clearCache() { - self::$mObjects = []; + return MediaWikiServices::getInstance()->getMagicWordFactory()->getDoubleUnderscoreArray(); } /** diff --git a/includes/MagicWordFactory.php b/includes/MagicWordFactory.php new file mode 100644 index 0000000000..11ed0a7a02 --- /dev/null +++ b/includes/MagicWordFactory.php @@ -0,0 +1,261 @@ + int ] + */ + private $mCacheTTLs = [ + 'currentmonth' => 86400, + 'currentmonth1' => 86400, + 'currentmonthname' => 86400, + 'currentmonthnamegen' => 86400, + 'currentmonthabbrev' => 86400, + 'currentday' => 3600, + 'currentday2' => 3600, + 'currentdayname' => 3600, + 'currentyear' => 86400, + 'currenttime' => 3600, + 'currenthour' => 3600, + 'localmonth' => 86400, + 'localmonth1' => 86400, + 'localmonthname' => 86400, + 'localmonthnamegen' => 86400, + 'localmonthabbrev' => 86400, + 'localday' => 3600, + 'localday2' => 3600, + 'localdayname' => 3600, + 'localyear' => 86400, + 'localtime' => 3600, + 'localhour' => 3600, + 'numberofarticles' => 3600, + 'numberoffiles' => 3600, + 'numberofedits' => 3600, + 'currentweek' => 3600, + 'currentdow' => 3600, + 'localweek' => 3600, + 'localdow' => 3600, + 'numberofusers' => 3600, + 'numberofactiveusers' => 3600, + 'numberofpages' => 3600, + 'currentversion' => 86400, + 'currenttimestamp' => 3600, + 'localtimestamp' => 3600, + 'pagesinnamespace' => 3600, + 'numberofadmins' => 3600, + 'numberingroup' => 3600, + ]; + + /** @var string[] */ + private $mDoubleUnderscoreIDs = [ + 'notoc', + 'nogallery', + 'forcetoc', + 'toc', + 'noeditsection', + 'newsectionlink', + 'nonewsectionlink', + 'hiddencat', + 'index', + 'noindex', + 'staticredirect', + 'notitleconvert', + 'nocontentconvert', + ]; + + /** @var string[] */ + private $mSubstIDs = [ + 'subst', + 'safesubst', + ]; + + /** @var array [ string => MagicWord ] */ + private $mObjects = []; + + /** @var MagicWordArray */ + private $mDoubleUnderscoreArray = null; + + /**#@-*/ + + /** + * Factory: creates an object representing an ID + * + * @param string $id The internal name of the magic word + * + * @return MagicWord + */ + public function get( $id ) { + if ( !isset( $this->mObjects[$id] ) ) { + $mw = new MagicWord(); + $mw->load( $id ); + $this->mObjects[$id] = $mw; + } + return $this->mObjects[$id]; + } + + /** + * Get an array of parser variable IDs + * + * @return string[] + */ + public function getVariableIDs() { + if ( !$this->mVariableIDsInitialised ) { + # Get variable IDs + Hooks::run( 'MagicWordwgVariableIDs', [ &$this->mVariableIDs ] ); + $this->mVariableIDsInitialised = true; + } + return $this->mVariableIDs; + } + + /** + * Get an array of parser substitution modifier IDs + * @return string[] + */ + public function getSubstIDs() { + return $this->mSubstIDs; + } + + /** + * Allow external reads of TTL array + * + * @param string $id + * @return int + */ + public function getCacheTTL( $id ) { + if ( array_key_exists( $id, $this->mCacheTTLs ) ) { + return $this->mCacheTTLs[$id]; + } else { + return -1; + } + } + + /** + * Get a MagicWordArray of double-underscore entities + * + * @return MagicWordArray + */ + public function getDoubleUnderscoreArray() { + if ( is_null( $this->mDoubleUnderscoreArray ) ) { + Hooks::run( 'GetDoubleUnderscoreIDs', [ &$this->mDoubleUnderscoreIDs ] ); + $this->mDoubleUnderscoreArray = new MagicWordArray( $this->mDoubleUnderscoreIDs ); + } + return $this->mDoubleUnderscoreArray; + } +} diff --git a/includes/MediaWikiServices.php b/includes/MediaWikiServices.php index fba15c1a2d..f891042aae 100644 --- a/includes/MediaWikiServices.php +++ b/includes/MediaWikiServices.php @@ -51,6 +51,7 @@ use TitleFormatter; use TitleParser; use VirtualRESTServiceClient; use MediaWiki\Interwiki\InterwikiLookup; +use MagicWordFactory; /** * Service locator for MediaWiki core services. @@ -864,6 +865,14 @@ class MediaWikiServices extends ServiceContainer { return $this->getService( 'ConfigRepository' ); } + /** + * @since 1.32 + * @return MagicWordFactory + */ + public function getMagicWordFactory() { + return $this->getService( 'MagicWordFactory' ); + } + /////////////////////////////////////////////////////////////////////////// // NOTE: When adding a service getter here, don't forget to add a test // case for it in MediaWikiServicesTest::provideGetters() and in diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index 7d49080902..0c63d4c730 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -600,6 +600,11 @@ return [ ); }, + 'MagicWordFactory' => function ( MediaWikiServices $services ) { + global $wgContLang; + return new MagicWordFactory( $wgContLang ); + }, + /////////////////////////////////////////////////////////////////////////// // NOTE: When adding a service here, don't forget to add a getter function // in the MediaWikiServices class. The convenience getter should just call diff --git a/tests/parser/ParserTestRunner.php b/tests/parser/ParserTestRunner.php index 5eb91c37a1..26e4e9f5a4 100644 --- a/tests/parser/ParserTestRunner.php +++ b/tests/parser/ParserTestRunner.php @@ -1152,7 +1152,7 @@ class ParserTestRunner { $lang->resetNamespaces(); $setup['wgContLang'] = $lang; $reset = function () { - MagicWord::clearCache(); + MediaWikiServices::getInstance()->resetServiceForTesting( 'MagicWordFactory' ); $this->resetTitleServices(); }; $setup[] = $reset; diff --git a/tests/phpunit/includes/ExtraParserTest.php b/tests/phpunit/includes/ExtraParserTest.php index 164c83c7e4..94de0880d3 100644 --- a/tests/phpunit/includes/ExtraParserTest.php +++ b/tests/phpunit/includes/ExtraParserTest.php @@ -1,5 +1,7 @@ options->setTemplateCallback( [ __CLASS__, 'statelessFetchTemplate' ] ); $this->parser = new Parser; - MagicWord::clearCache(); + MediaWikiServices::getInstance()->resetServiceForTesting( 'MagicWordFactory' ); } /** diff --git a/tests/phpunit/includes/MediaWikiServicesTest.php b/tests/phpunit/includes/MediaWikiServicesTest.php index 7763afff3a..4189e93d6b 100644 --- a/tests/phpunit/includes/MediaWikiServicesTest.php +++ b/tests/phpunit/includes/MediaWikiServicesTest.php @@ -365,6 +365,7 @@ class MediaWikiServicesTest extends MediaWikiTestCase { 'PreferencesFactory' => [ 'PreferencesFactory', PreferencesFactory::class ], 'ActorMigration' => [ 'ActorMigration', ActorMigration::class ], 'ConfigRepository' => [ 'ConfigRepository', \MediaWiki\Config\ConfigRepository::class ], + 'MagicWordFactory' => [ 'MagicWordFactory', MagicWordFactory::class ], ]; } diff --git a/tests/phpunit/includes/content/WikitextContentHandlerTest.php b/tests/phpunit/includes/content/WikitextContentHandlerTest.php index 59984d85e9..4bb1ed2501 100644 --- a/tests/phpunit/includes/content/WikitextContentHandlerTest.php +++ b/tests/phpunit/includes/content/WikitextContentHandlerTest.php @@ -1,5 +1,7 @@ resetNamespaces(); - MagicWord::clearCache(); + MediaWikiServices::getInstance()->resetServiceForTesting( 'MagicWordFactory' ); if ( is_string( $title ) ) { $title = Title::newFromText( $title );