X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Fconfig%2FConfigFactory.php;h=e175765431ff62ba6eb7045f682208af5b7bce84;hp=09b0baa7be85f716ee595ab0bd6ca53ffe08a63b;hb=827c6bfa416d9d0de8cc8e22f9f3fa36d8129d44;hpb=c8b0af1546e339e515f8f835c184db952ae30aad diff --git a/includes/config/ConfigFactory.php b/includes/config/ConfigFactory.php index 09b0baa7be..e175765431 100644 --- a/includes/config/ConfigFactory.php +++ b/includes/config/ConfigFactory.php @@ -20,13 +20,15 @@ * * @file */ +use MediaWiki\Services\SalvageableService; +use Wikimedia\Assert\Assert; /** * Factory class to create Config objects * * @since 1.23 */ -class ConfigFactory { +class ConfigFactory implements SalvageableService { /** * Map of config name => callback @@ -50,6 +52,41 @@ class ConfigFactory { return \MediaWiki\MediaWikiServices::getInstance()->getConfigFactory(); } + /** + * Re-uses existing Cache objects from $other. Cache objects are only re-used if the + * registered factory function for both is the same. Cache config is not copied, + * and only instances of caches defined on this instance with the same config + * are copied. + * + * @see SalvageableService::salvage() + * + * @param SalvageableService $other The object to salvage state from. $other must have the + * exact same type as $this. + */ + public function salvage( SalvageableService $other ) { + Assert::parameterType( self::class, $other, '$other' ); + + /** @var ConfigFactory $other */ + foreach ( $other->factoryFunctions as $name => $otherFunc ) { + if ( !isset( $this->factoryFunctions[$name] ) ) { + continue; + } + + // if the callback function is the same, salvage the Cache object + // XXX: Closures are never equal! + if ( isset( $other->configs[$name] ) + && $this->factoryFunctions[$name] == $otherFunc + ) { + $this->configs[$name] = $other->configs[$name]; + unset( $other->configs[$name] ); + } + } + + // disable $other + $other->factoryFunctions = []; + $other->configs = []; + } + /** * @return string[] */ @@ -62,28 +99,16 @@ class ConfigFactory { * Will override if it's already registered. * Use "*" for $name to provide a fallback config for all unknown names. * @param string $name - * @param callable|Config $callback A factory callabck that takes this ConfigFactory + * @param callable|Config $callback A factory callback that takes this ConfigFactory * as an argument and returns a Config instance, or an existing Config instance. * @throws InvalidArgumentException If an invalid callback is provided */ public function register( $name, $callback ) { - if ( $callback instanceof Config ) { - $instance = $callback; - - // Register a callback anyway, for consistency. Note that getConfigNames() - // relies on $factoryFunctions to have all config names. - $callback = function() use ( $instance ) { - return $instance; - }; - } else { - $instance = null; - } - - if ( !is_callable( $callback ) ) { + if ( !is_callable( $callback ) && !( $callback instanceof Config ) ) { throw new InvalidArgumentException( 'Invalid callback provided' ); } - $this->configs[$name] = $instance; + unset( $this->configs[$name] ); $this->factoryFunctions[$name] = $callback; } @@ -105,7 +130,13 @@ class ConfigFactory { if ( !isset( $this->factoryFunctions[$key] ) ) { throw new ConfigException( "No registered builder available for $name." ); } - $conf = call_user_func( $this->factoryFunctions[$key], $this ); + + if ( $this->factoryFunctions[$key] instanceof Config ) { + $conf = $this->factoryFunctions[$key]; + } else { + $conf = call_user_func( $this->factoryFunctions[$key], $this ); + } + if ( $conf instanceof Config ) { $this->configs[$name] = $conf; } else {