X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fconfig%2FConfigFactory.php;h=cd25352dac3cef100361158d4b93556c06d8591b;hb=9c5dae53155a950edb1e712bbda59fa8732fddd8;hp=4b803d8eaf4c7a6357c054f4f43cdd37f0e1e7fc;hpb=220e11d65165aee4724a043fa0e0f27083f5865a;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/config/ConfigFactory.php b/includes/config/ConfigFactory.php index 4b803d8eaf..cd25352dac 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 @@ -51,16 +53,62 @@ class ConfigFactory { } /** - * Register a new config factory function - * Will override if it's already registered + * 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[] + */ + public function getConfigNames() { + return array_keys( $this->factoryFunctions ); + } + + /** + * Register a new config factory function. + * Will override if it's already registered. + * Use "*" for $name to provide a fallback config for all unknown names. * @param string $name - * @param callable $callback That takes this ConfigFactory as an argument + * @param callable|Config $callback A factory callabck 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 ( !is_callable( $callback ) ) { + if ( !is_callable( $callback ) && !( $callback instanceof Config ) ) { throw new InvalidArgumentException( 'Invalid callback provided' ); } + + unset( $this->configs[$name] ); $this->factoryFunctions[$name] = $callback; } @@ -75,10 +123,20 @@ class ConfigFactory { */ public function makeConfig( $name ) { if ( !isset( $this->configs[$name] ) ) { - if ( !isset( $this->factoryFunctions[$name] ) ) { + $key = $name; + if ( !isset( $this->factoryFunctions[$key] ) ) { + $key = '*'; + } + if ( !isset( $this->factoryFunctions[$key] ) ) { throw new ConfigException( "No registered builder available for $name." ); } - $conf = call_user_func( $this->factoryFunctions[$name], $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 { @@ -88,4 +146,5 @@ class ConfigFactory { return $this->configs[$name]; } + }