'', 'visible' => true, ); } return array( // Shop title (empty: the WooCommerce title) and visibility of each WooCommerce tab, for every product. 'natives' => $natives, // Order of the WooCommerce tabs on products that have no order of their own. 'native_order' => Tabs::NATIVE, // Title of the tab repeated as a heading at the top of its panel, as WooCommerce does for Description. 'heading' => true, // Tabs shown as an accordion on screens narrower than accordion_width (pixels). 'accordion' => true, 'accordion_width' => 768, // A tab without a translation in the language of the page is hidden instead of showing the original text. 'hide_untranslated' => false, // Run the full the_content filter on tab content instead of the core formatting only. 'the_content' => false, // Delete tabs, library and settings when the plugin is deleted. 'delete_data' => false, // Apply the filters and classes of Custom Product Tabs (YIKES), so that customizations made for it keep working. 'yikes_compat' => false, // Prodtabs menu in the main WordPress menu: overview, shared tabs, settings. Off, everything stays under Products and WooCommerce. 'menu' => true, ); } /** Settings merged with the defaults. */ public static function all(): array { return self::sanitize( get_option( self::OPTION, array() ) ); } /** * One setting. * * @param string $key Setting name. * @return mixed */ public static function get( string $key ) { $all = self::all(); return $all[ $key ] ?? null; } /** * Cleans a settings array; missing values take their default. * * @param mixed $value Raw settings. */ public static function sanitize( $value ): array { $value = is_array( $value ) ? $value : array(); $defaults = self::defaults(); $out = $defaults; foreach ( Tabs::NATIVE as $key ) { $raw = isset( $value['natives'][ $key ] ) && is_array( $value['natives'][ $key ] ) ? $value['natives'][ $key ] : array(); if ( isset( $raw['title'] ) ) { $out['natives'][ $key ]['title'] = sanitize_text_field( (string) $raw['title'] ); } if ( isset( $raw['visible'] ) ) { $out['natives'][ $key ]['visible'] = Tabs::to_bool( $raw['visible'] ); } } if ( isset( $value['native_order'] ) && is_array( $value['native_order'] ) ) { $order = array_values( array_intersect( array_map( 'strval', $value['native_order'] ), Tabs::NATIVE ) ); $order = array_values( array_unique( $order ) ); if ( count( $order ) === count( Tabs::NATIVE ) ) { $out['native_order'] = $order; } } foreach ( array( 'heading', 'the_content', 'delete_data', 'yikes_compat', 'menu', 'accordion', 'hide_untranslated' ) as $flag ) { if ( isset( $value[ $flag ] ) ) { $out[ $flag ] = Tabs::to_bool( $value[ $flag ] ); } } if ( isset( $value['accordion_width'] ) && is_numeric( $value['accordion_width'] ) ) { $out['accordion_width'] = max( 320, min( 2000, (int) $value['accordion_width'] ) ); } return $out; } /** * Shop title chosen for a WooCommerce tab; empty when it keeps the WooCommerce title. With WPML or Polylang the * option arrives already translated (admin texts of wpml-config.xml). * * @param string $key Native key. */ public static function native_title( string $key ): string { $natives = self::get( 'natives' ); return Multilingual::native_title( (string) ( $natives[ $key ]['title'] ?? '' ), $key ); } }