`. * * @package Aisentic */ defined( 'ABSPATH' ) || exit; use Aisentic\Database\Migration; /** * Rewrites the aisentic_settings option. Touches no database table. */ // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- Migration_Runner binds the class name to the filename; renaming would re-run the migration. class Move_Public_Chat_Settings_To_Public_Agent extends Migration { /** * Option that holds every plugin setting. * * @var string */ const OPTION = 'aisentic_settings'; /** * Keys that describe the one shared widget. * * @var string[] */ const WIDGET_KEYS = [ 'botName', 'headline', 'teaserMessage', 'brandColor', 'position', 'rateLimitPerHour', 'maxToolCallsPerTurn', ]; /** * Keys that stay with each integration. * * @var string[] */ const INTEGRATION_KEYS = [ 'enabled', 'recommendedLimit', 'searchCacheTtlSeconds', 'outOfScopeMessage', 'starterPrompts', ]; /** * Serial number for execution order. * * @var int */ protected int $serial = 4; /** * Plugin version when this migration was written. * * @var string */ protected string $version = '1.2.0'; /** * Move the old keys onto the new shape. * * @return void */ public function up() { $settings = get_option( self::OPTION, null ); if ( ! is_array( $settings ) || ! isset( $settings['publicChat'] ) || ! is_array( $settings['publicChat'] ) ) { return; } $public_chat = $settings['publicChat']; // Already migrated. Never touch a value the site owner has edited since. if ( isset( $public_chat['widget'] ) ) { return; } $woocommerce = isset( $public_chat['woocommerce'] ) && is_array( $public_chat['woocommerce'] ) ? $public_chat['woocommerce'] : []; $eventin = isset( $public_chat['eventin'] ) && is_array( $public_chat['eventin'] ) ? $public_chat['eventin'] : []; if ( ! $woocommerce && ! $eventin ) { return; } /* * WooCommerce wins every shared key: its look-and-feel values are the * only ones the widget ever read, so they are what the site owner * actually saw. Eventin's copies fill in only on a site that never had * WooCommerce. */ $widget = []; foreach ( self::WIDGET_KEYS as $key ) { if ( array_key_exists( $key, $woocommerce ) ) { $widget[ $key ] = $woocommerce[ $key ]; } elseif ( array_key_exists( $key, $eventin ) ) { $widget[ $key ] = $eventin[ $key ]; } } $integrations = []; $old_blocks = [ 'woocommerce' => $woocommerce, 'eventin' => $eventin, ]; foreach ( $old_blocks as $id => $old ) { if ( ! $old ) { continue; } $values = []; foreach ( self::INTEGRATION_KEYS as $key ) { if ( array_key_exists( $key, $old ) ) { $values[ $key ] = $old[ $key ]; } } if ( $values ) { $integrations[ $id ] = $values; } } unset( $public_chat['woocommerce'], $public_chat['eventin'] ); if ( $widget ) { $public_chat['widget'] = $widget; } if ( $integrations ) { $public_chat['integrations'] = $integrations; } $settings['publicChat'] = $public_chat; update_option( self::OPTION, $settings ); } /** * Put the old key shape back. * * Eventin's own look-and-feel values were dropped by up() because nothing * read them; they are not restored. * * @return void */ public function down() { $settings = get_option( self::OPTION, null ); if ( ! is_array( $settings ) || ! isset( $settings['publicChat'] ) || ! is_array( $settings['publicChat'] ) ) { return; } $public_chat = $settings['publicChat']; if ( ! isset( $public_chat['widget'] ) ) { return; } $widget = is_array( $public_chat['widget'] ) ? $public_chat['widget'] : []; $integrations = isset( $public_chat['integrations'] ) && is_array( $public_chat['integrations'] ) ? $public_chat['integrations'] : []; foreach ( $integrations as $id => $values ) { if ( ! is_array( $values ) ) { continue; } // Only WooCommerce ever read the shared keys, so only it gets them back. $public_chat[ $id ] = 'woocommerce' === $id ? array_merge( $values, $widget ) : $values; } unset( $public_chat['widget'], $public_chat['integrations'] ); $settings['publicChat'] = $public_chat; update_option( self::OPTION, $settings ); } }