settings ) { $stored = get_option( self::OPTION, array() ); $this->settings = self::merge( Schema::default_settings(), is_array( $stored ) ? $stored : array() ); } return $this->settings; } /** * Saves already-normalised settings. * * @param array $settings Settings. */ public function update( array $settings ): array { update_option( self::OPTION, $settings, false ); $this->settings = null; return $this->get(); } /** * Whether the free shipping bar is enabled. */ public function bar_enabled(): bool { return ! empty( $this->get()['free_shipping_bar']['enabled'] ); } /** * Recursive merge where stored values win and missing keys take defaults. * * @param array $defaults Defaults. * @param array $stored Stored. */ public static function merge( array $defaults, array $stored ): array { foreach ( $defaults as $key => $value ) { if ( ! array_key_exists( $key, $stored ) ) { $stored[ $key ] = $value; } elseif ( is_array( $value ) && is_array( $stored[ $key ] ) && ! array_is_list( $value ) ) { $stored[ $key ] = self::merge( $value, $stored[ $key ] ); } } return $stored; } }