'auto', 'font_library' => '0', 'delete_on_uninstall' => '0', ]; } /** * Returns all values with defaults applied. * * @return array */ public static function all() { $saved = get_option( self::OPTION, [] ); if ( ! is_array( $saved ) ) { $saved = []; } return wp_parse_args( $saved, self::defaults() ); } /** * Returns one value. * * @param string $key Setting key. * @return mixed|null */ public static function get( $key ) { $all = self::all(); return isset( $all[ $key ] ) ? $all[ $key ] : null; } /** * Returns the theme integration modes with a label and one sentence each. * * @return array mode => [ label, description ] */ public static function get_modes() { return [ 'auto' => [ 'label' => esc_html__( 'Automatic', 'headfoot' ), 'description' => esc_html__( 'The plugin picks the best method for the active theme.', 'headfoot' ), ], 'theme_support' => [ 'label' => esc_html__( 'Theme support', 'headfoot' ), 'description' => esc_html__( 'The plugin renders nothing by itself. The theme calls headfoot_render_header() and headfoot_render_footer().', 'headfoot' ), ], 'generic' => [ 'label' => esc_html__( 'Generic fallback', 'headfoot' ), 'description' => esc_html__( 'The plugin replaces the header.php and footer.php files of the theme.', 'headfoot' ), ], 'off' => [ 'label' => esc_html__( 'Off', 'headfoot' ), 'description' => esc_html__( 'The plugin renders nothing. The shortcode still works.', 'headfoot' ), ], ]; } /** * Returns the URL of the configuration page. * * @return string */ public static function get_url() { return admin_url( 'themes.php?page=' . self::PAGE_SLUG ); } /** * Registers the page under Appearance. * * The page needs Appearance as parent for the WordPress access check, * because the post type list also lives there. The menu entry goes away * again in hide_menu_entry(), and the page shows as a tab instead. * * @return void */ public function add_page() { add_submenu_page( 'themes.php', esc_html__( 'Header & Footer Settings', 'headfoot' ), esc_html__( 'Header & Footer Settings', 'headfoot' ), self::CAPABILITY, self::PAGE_SLUG, [ $this, 'render_page' ] ); } /** * Removes the menu entry of the page. The page stays registered and reachable. * * @return void */ public function hide_menu_entry() { remove_submenu_page( 'themes.php', self::PAGE_SLUG ); } /** * Keeps the menu item Header & Footer highlighted on the configuration page. * * @param string|null $submenu_file Current submenu file. * @return string|null */ public function highlight_menu( $submenu_file ) { if ( self::is_settings_screen() ) { return self::LIST_URL; } return $submenu_file; } /** * Tells whether the current screen is the configuration page. * * @return bool */ public static function is_settings_screen() { $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; return $screen && 'appearance_page_' . self::PAGE_SLUG === $screen->id; } /** * Prints the tabs Templates and Settings on the list table and on the configuration page. * * @return void */ public function render_tabs() { $screen = get_current_screen(); if ( ! $screen ) { return; } $on_list = 'edit-headfoot_template' === $screen->id; $on_settings = self::is_settings_screen() && doing_action( 'all_admin_notices' ) === false; if ( ! $on_list && ! $on_settings ) { return; } if ( ! current_user_can( self::CAPABILITY ) ) { return; } // On the list table the tabs travel with the notices below the heading. if ( $on_list ) { echo '
'; } ?> '; } } /** * Registers the option, the section, and the fields. * * @return void */ public function register() { register_setting( self::PAGE_SLUG, self::OPTION, [ 'type' => 'array', 'sanitize_callback' => [ __CLASS__, 'sanitize' ], 'default' => self::defaults(), ] ); add_settings_section( 'headfoot_main', '', '__return_empty_string', self::PAGE_SLUG ); add_settings_field( 'theme_mode', esc_html__( 'Theme Integration', 'headfoot' ), [ $this, 'field_theme_mode' ], self::PAGE_SLUG, 'headfoot_main' ); add_settings_field( 'detected_method', esc_html__( 'Detected Method', 'headfoot' ), [ $this, 'field_detected_method' ], self::PAGE_SLUG, 'headfoot_main' ); add_settings_field( 'font_library', esc_html__( 'WordPress Font Library', 'headfoot' ), [ $this, 'field_font_library' ], self::PAGE_SLUG, 'headfoot_main' ); add_settings_field( 'delete_on_uninstall', esc_html__( 'Uninstall', 'headfoot' ), [ $this, 'field_delete_on_uninstall' ], self::PAGE_SLUG, 'headfoot_main' ); } /** * Sanitizes the option. * * @param mixed $input Raw option value. * @return array */ public static function sanitize( $input ) { $input = is_array( $input ) ? $input : []; $clean = self::defaults(); if ( isset( $input['theme_mode'] ) && isset( self::get_modes()[ $input['theme_mode'] ] ) ) { $clean['theme_mode'] = $input['theme_mode']; } $clean['font_library'] = empty( $input['font_library'] ) ? '0' : '1'; $clean['delete_on_uninstall'] = empty( $input['delete_on_uninstall'] ) ? '0' : '1'; return $clean; } /** * Prints the theme integration radio group. * * @return void */ public function field_theme_mode() { $current = self::get( 'theme_mode' ); echo '
'; foreach ( self::get_modes() as $mode => $texts ) { printf( '', esc_attr( self::OPTION ), esc_attr( $mode ), checked( $current, $mode, false ), esc_html( $texts['label'] ), esc_html( $texts['description'] ) ); } echo '
'; } /** * Prints the method that the automatic mode picks for the active theme. * * @return void */ public function field_detected_method() { $auto = Compat\Theme_Loader::detect_auto_method(); $active = Compat\Theme_Loader::get_method(); echo '

' . esc_html( Compat\Theme_Loader::describe_method( $auto ) ) . '

'; if ( $auto !== $active ) { printf( '

%s

', sprintf( /* translators: %s: Method description. */ esc_html__( 'Active now: %s', 'headfoot' ), esc_html( Compat\Theme_Loader::describe_method( $active ) ) ) ); } } /** * Prints the font library switch. * * @return void */ public function field_font_library() { $supported = Elementor\Font_Library::is_supported(); printf( '', esc_attr( self::OPTION ), checked( self::get( 'font_library' ), '1', false ), disabled( ! $supported, true, false ), esc_html__( 'Enable WordPress Font Library', 'headfoot' ) ); echo '

' . esc_html__( 'Shows the font families of the WordPress font library in the Elementor font picker, in the group WordPress Font Library.', 'headfoot' ) . '

'; if ( ! $supported ) { echo '

' . esc_html__( 'This WordPress version has no font library. WordPress 6.5 or newer is needed.', 'headfoot' ) . '

'; return; } $count = count( Elementor\Font_Library::get_families( false ) ); echo '

' . esc_html( sprintf( /* translators: %d: Number of font families. */ _n( 'The library holds %d font family with font files.', 'The library holds %d font families with font files.', $count, 'headfoot' ), $count ) ) . '

'; if ( ! function_exists( 'wp_is_block_theme' ) || ! wp_is_block_theme() ) { echo '

' . esc_html__( 'The font library screen is part of the Site Editor, so the active classic theme offers no screen to upload fonts. Fonts that already exist in the library still work.', 'headfoot' ) . '

'; } } /** * Prints the uninstall checkbox. * * @return void */ public function field_delete_on_uninstall() { printf( '', esc_attr( self::OPTION ), checked( self::get( 'delete_on_uninstall' ), '1', false ), esc_html__( 'Delete all templates and the plugin configuration when the plugin is deleted.', 'headfoot' ) ); } /** * Prints the configuration page. * * @return void */ public function render_page() { if ( ! current_user_can( self::CAPABILITY ) ) { return; } ?>

render_tabs(); ?>