*/ private array $items; /** * @var Config_Loader */ private Config_Loader $loader; /** * Whether we're queued up to save on shutdown. * * @var bool */ private bool $will_save = false; /** * @param Config_Loader $loader The configuration loader. */ public function __construct( Config_Loader $loader ) { $this->loader = $loader; $this->items = $this->loader->load(); } /** * Get all the current configuration items. * * @return array */ public function all(): array { return $this->items; } /** * Get a configuration value. * * @param string $key The config key. * * @return mixed */ public function get( string $key ) { return Arr::get( $this->items, explode( '.', $key ) ); } /** * Sets a config item in memory. * * @param string $key The key to set. * @param mixed $value The value to set. * * @throws InvalidArgumentException If you try to set a key that does not exist in the defaults. * * @return Config */ public function set( string $key, $value ): Config { if ( ! Arr::exists( $this->items, $key ) ) { throw new InvalidArgumentException( sprintf( 'Invalid config key: "%s"', $key ) ); } $this->items = Arr::set( $this->items, explode( '.', $key ), $value ); return $this; } /** * Queue up config to save its state to the database on shutdown. * * This prevents writing to the database / config file multiple times. * * @return Config */ public function queue(): Config { $this->will_save = true; return $this; } /** * Manually call hooks that perform config database saves. * * @return void */ public function save(): void { do_action( 'solidwp/performance/config/save' ); } /** * Save all changes on shutdown. * * @see \SolidWP\Performance\Shutdown\Provider::register() * * @action shutdown * @action solidwp/performance/terminate * * @return void */ public function terminate(): void { if ( ! $this->will_save ) { return; } $this->save(); // Shutdown terminable tasks run twice, we only need to save once. $this->will_save = false; } /** * Refresh the configuration state, as the database values may have changed * based on where we are in the request lifecycle. * * @return Config */ public function refresh(): Config { $this->items = $this->loader->load(); return $this; } }