*/ public static function get_enabled_ids() { $raw = get_option( self::OPTION, null ); if ( null === $raw || false === $raw ) { return self::default_enabled_ids(); } if ( ! is_array( $raw ) ) { return self::default_enabled_ids(); } $ids = array(); foreach ( $raw as $id ) { $id = sanitize_key( (string) $id ); if ( '' !== $id && self::is_known( $id ) && self::is_activatable( $id ) ) { $ids[] = $id; } } return array_values( array_unique( $ids ) ); } /** * @param string $id Element id. * @return bool */ public static function is_enabled( $id ) { $id = sanitize_key( (string) $id ); return in_array( $id, self::get_enabled_ids(), true ); } /** * @param list $ids Enabled IDs. * @return list Sanitised saved IDs. */ public static function save( array $ids ) { $clean = array(); foreach ( $ids as $id ) { $id = sanitize_key( (string) $id ); if ( '' === $id || ! self::is_known( $id ) || ! self::is_activatable( $id ) ) { continue; } $clean[] = $id; } $clean = array_values( array_unique( $clean ) ); update_option( self::OPTION, $clean, false ); /** * Fires after enabled elements are saved. * * @param list $clean Enabled IDs. */ do_action( 'reactwoo/atomic/enabled_elements_saved', $clean ); return $clean; } /** * Enable recommended (and currently activatable) elements. * * @return list */ public static function enable_recommended() { $ids = array(); foreach ( Catalog::all() as $item ) { if ( empty( $item['recommended'] ) || empty( $item['id'] ) ) { continue; } $id = (string) $item['id']; if ( self::is_activatable( $id ) ) { $ids[] = $id; } } return self::save( $ids ); } /** * Estimated frontend payload in KB for currently enabled activatable elements. * * @return int */ public static function estimated_payload_kb() { $total = 0; $enabled = array_fill_keys( self::get_enabled_ids(), true ); foreach ( Catalog::all() as $item ) { $id = isset( $item['id'] ) ? (string) $item['id'] : ''; if ( '' === $id || empty( $enabled[ $id ] ) || ! self::is_activatable( $id ) ) { continue; } $total += isset( $item['asset_size'] ) ? (int) $item['asset_size'] : 0; } return $total; } /** * @return list */ public static function default_enabled_ids() { $ids = array(); foreach ( Catalog::all() as $item ) { if ( empty( $item['enabled_by_default'] ) || empty( $item['id'] ) ) { continue; } $id = (string) $item['id']; if ( self::is_activatable( $id ) ) { $ids[] = $id; } } return $ids; } /** * @param string $id Element id. * @return bool */ public static function is_known( $id ) { return null !== Catalog::get( $id ); } /** * Free edition cannot activate Pro elements. * * @param string $id Element id. * @return bool */ public static function is_activatable( $id ) { $item = Catalog::get( $id ); if ( ! $item ) { return false; } $edition = isset( $item['edition'] ) ? (string) $item['edition'] : 'free'; if ( 'pro' === $edition && ! Edition::is_pro() ) { return false; } return true; } /** * IDs that have already been auto-seeded from catalog defaults. * Used so newly catalogued `enabled_by_default` widgets appear without * re-enabling IDs the admin deliberately turned off. */ const SEEDED_OPTION = 'reactwoo_atomic_seeded_default_ids'; /** * Ensure option exists after schema upgrade, then seed any new defaults. * * @return void */ public static function maybe_init_option() { if ( false === get_option( self::OPTION, false ) ) { $defaults = self::default_enabled_ids(); add_option( self::OPTION, $defaults, '', false ); update_option( self::SEEDED_OPTION, $defaults, false ); return; } self::seed_new_defaults(); } /** * Enable catalog rows marked `enabled_by_default` that have never been seeded. * * Fixes Local sites whose `reactwoo_atomic_enabled_elements` option was * written before Modal (etc.) existed — those widgets never auto-appeared * in the Atomic panel until manually toggled under Atomic → Elements. * * @return list IDs newly enabled this call (may be empty). */ public static function seed_new_defaults() { $defaults = self::default_enabled_ids(); $seeded = get_option( self::SEEDED_OPTION, null ); if ( null === $seeded || false === $seeded || ! is_array( $seeded ) ) { // First boot of this feature: treat current enabled set as already // considered, then seed only defaults that are still missing. $seeded = self::get_enabled_ids(); update_option( self::SEEDED_OPTION, $seeded, false ); } $seeded_clean = array(); foreach ( $seeded as $id ) { $id = sanitize_key( (string) $id ); if ( '' !== $id ) { $seeded_clean[] = $id; } } $seeded_clean = array_values( array_unique( $seeded_clean ) ); $to_seed = array(); foreach ( $defaults as $id ) { if ( ! in_array( $id, $seeded_clean, true ) ) { $to_seed[] = $id; } } if ( ! $to_seed ) { return array(); } $enabled = self::get_enabled_ids(); $merged = array_values( array_unique( array_merge( $enabled, $to_seed ) ) ); update_option( self::OPTION, $merged, false ); update_option( self::SEEDED_OPTION, array_values( array_unique( array_merge( $seeded_clean, $to_seed ) ) ), false ); /** * Fires after new default-enabled catalog IDs are seeded into the option. * * @param list $to_seed Newly enabled IDs. * @param list $merged Full enabled list after seed. */ do_action( 'reactwoo/atomic/enabled_elements_seeded', $to_seed, $merged ); return $to_seed; } }