*/ public static function get_default_settings() { $defaults = array( 'automatic_processing' => false, 'enabled_post_types' => array( 'post', 'page' ), 'enable_diagrams' => true, 'diagram_mode' => 'compact', 'default_diagram_width' => 20, 'default_song_scale' => 1, 'chord_prompt_font_size' => 14, 'block_spacing' => 12, 'section_break_spacing' => 24, 'show_controls' => true, 'enable_print_button' => true, 'print_show_diagrams' => true, 'default_tuning' => 'gCEA', 'enharmonic_preference' => 'auto', 'print_footer_notice' => '', 'remove_on_uninstall' => false, ); return apply_filters( 'da_plectrum_default_settings', $defaults ); } /** * Register plugin settings. * * @return void */ public function register_settings() { register_setting( 'da_plectrum_settings_group', DA_PLECTRUM_OPTION_KEY, array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_settings' ), 'default' => self::get_default_settings(), ) ); add_settings_section( 'da_plectrum_general', __( 'General', 'plectrum' ), '__return_empty_string', 'da-plectrum-settings' ); add_settings_field( 'automatic_processing', __( 'Enable automatic processing', 'plectrum' ), array( $this, 'render_checkbox_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'automatic_processing', 'description' => __( 'Automatically process chord-marked content on selected post types.', 'plectrum' ), ) ); add_settings_field( 'enabled_post_types', __( 'Enabled post types', 'plectrum' ), array( $this, 'render_post_types_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'enabled_post_types', 'description' => __( 'Choose which public post types should be processed automatically when enabled.', 'plectrum' ), ) ); add_settings_field( 'show_controls', __( 'Show controls by default', 'plectrum' ), array( $this, 'render_checkbox_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'show_controls', 'description' => __( 'Display transpose, size, and print controls when available.', 'plectrum' ), ) ); add_settings_field( 'enable_diagrams', __( 'Enable diagrams', 'plectrum' ), array( $this, 'render_checkbox_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'enable_diagrams', 'description' => __( 'Allow chord diagrams to be shown in rendered songs.', 'plectrum' ), ) ); add_settings_field( 'diagram_mode', __( 'Default diagram mode', 'plectrum' ), array( $this, 'render_select_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'diagram_mode', 'options' => array( 'compact' => __( 'Chord names with compact diagrams', 'plectrum' ), 'names' => __( 'Chord names only', 'plectrum' ), ), 'description' => __( 'Choose the initial display mode for chord diagrams.', 'plectrum' ), ) ); add_settings_field( 'default_diagram_width', __( 'Default diagram width', 'plectrum' ), array( $this, 'render_number_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'default_diagram_width', 'min' => 12, 'max' => 80, 'step' => 1, 'suffix' => __( 'px', 'plectrum' ), 'description' => __( 'Sets the default chord diagram width in pixels before any visitor adjustments.', 'plectrum' ), ) ); add_settings_field( 'default_song_scale', __( 'Default chord/lyric size', 'plectrum' ), array( $this, 'render_number_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'default_song_scale', 'min' => 0.75, 'max' => 1.75, 'step' => 0.05, 'description' => __( 'Sets the starting display scale for rendered chord sheets. Use 1 for the standard size.', 'plectrum' ), ) ); add_settings_field( 'chord_prompt_font_size', __( 'Chord prompt font size', 'plectrum' ), array( $this, 'render_number_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'chord_prompt_font_size', 'min' => 8, 'max' => 48, 'step' => 1, 'suffix' => __( 'px', 'plectrum' ), 'description' => __( 'Sets the font size for chord prompts such as G7, Am, F, and D7.', 'plectrum' ), ) ); add_settings_field( 'block_spacing', __( 'Content block spacing', 'plectrum' ), array( $this, 'render_number_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'block_spacing', 'min' => 0, 'max' => 80, 'step' => 1, 'suffix' => __( 'px', 'plectrum' ), 'description' => __( 'Sets the default top margin between adjacent content blocks.', 'plectrum' ), ) ); add_settings_field( 'section_break_spacing', __( 'Section break spacing', 'plectrum' ), array( $this, 'render_number_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'section_break_spacing', 'min' => 0, 'max' => 120, 'step' => 1, 'suffix' => __( 'px', 'plectrum' ), 'description' => __( 'Sets the larger top margin used after blank lines in the source content.', 'plectrum' ), ) ); add_settings_field( 'enharmonic_preference', __( 'Enharmonic preference', 'plectrum' ), array( $this, 'render_select_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'enharmonic_preference', 'options' => array( 'auto' => __( 'Automatic', 'plectrum' ), 'preserve-source' => __( 'Preserve source spelling', 'plectrum' ), 'sharps' => __( 'Prefer sharps', 'plectrum' ), 'flats' => __( 'Prefer flats', 'plectrum' ), ), 'description' => __( 'Choose how transposed chord names should prefer sharp or flat spellings.', 'plectrum' ), ) ); add_settings_field( 'enable_print_button', __( 'Enable print button', 'plectrum' ), array( $this, 'render_checkbox_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'enable_print_button', 'description' => __( 'Show a print button in the song controls.', 'plectrum' ), ) ); add_settings_field( 'print_show_diagrams', __( 'Show diagrams in print', 'plectrum' ), array( $this, 'render_checkbox_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'print_show_diagrams', 'description' => __( 'Include chord diagrams when printing song content.', 'plectrum' ), ) ); add_settings_field( 'print_footer_notice', __( 'Print footer notice', 'plectrum' ), array( $this, 'render_textarea_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'print_footer_notice', 'description' => __( 'Optional notice appended to printed output. Supports {year}, {site_name}, {post_title}, and {author}.', 'plectrum' ), ) ); add_settings_field( 'remove_on_uninstall', __( 'Remove settings on uninstall', 'plectrum' ), array( $this, 'render_checkbox_field' ), 'da-plectrum-settings', 'da_plectrum_general', array( 'key' => 'remove_on_uninstall', 'description' => __( 'Delete plugin settings when the plugin is uninstalled.', 'plectrum' ), ) ); } /** * Register settings page. * * @return void */ public function register_settings_page() { $this->page_hook = add_menu_page( __( 'Plectrum', 'plectrum' ), __( 'Plectrum', 'plectrum' ), 'manage_options', 'da-plectrum', array( $this, 'render_settings_page' ), 'dashicons-format-audio', 58 ); } /** * Render settings page. * * @return void */ public function render_settings_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } $markup_example = implode( "\n", array( '[ukulele_chords]', 'A[Dm]las my love, you [C]do me wrong', 'To [Dm]cast me off dis[A]courteously;', 'And [Dm]I have loved you [C]oh so long,', 'De[Dm]lighting in [A7]your compa[D]ny,', '[/ukulele_chords]', ) ); ?>

$input Raw input. * @return array */ public function sanitize_settings( $input ) { $defaults = self::get_default_settings(); $output = array(); $output['automatic_processing'] = ! empty( $input['automatic_processing'] ); $output['enabled_post_types'] = $this->sanitize_post_types( $input['enabled_post_types'] ?? array() ); $output['show_controls'] = ! empty( $input['show_controls'] ); $output['enable_diagrams'] = ! empty( $input['enable_diagrams'] ); $output['enable_print_button'] = ! empty( $input['enable_print_button'] ); $output['print_show_diagrams'] = ! empty( $input['print_show_diagrams'] ); $output['remove_on_uninstall'] = ! empty( $input['remove_on_uninstall'] ); $output['diagram_mode'] = in_array( $input['diagram_mode'] ?? '', array( 'compact', 'names' ), true ) ? $input['diagram_mode'] : $defaults['diagram_mode']; $output['default_diagram_width'] = $this->sanitize_diagram_width( $input['default_diagram_width'] ?? $defaults['default_diagram_width'] ); $output['default_song_scale'] = $this->sanitize_song_scale( $input['default_song_scale'] ?? $defaults['default_song_scale'] ); $output['chord_prompt_font_size'] = $this->sanitize_chord_prompt_font_size( $input['chord_prompt_font_size'] ?? $defaults['chord_prompt_font_size'] ); $output['block_spacing'] = $this->sanitize_spacing( $input['block_spacing'] ?? $defaults['block_spacing'], 80 ); $output['section_break_spacing'] = $this->sanitize_spacing( $input['section_break_spacing'] ?? $defaults['section_break_spacing'], 120 ); $output['default_tuning'] = 'gCEA'; $output['enharmonic_preference'] = in_array( $input['enharmonic_preference'] ?? '', array( 'auto', 'preserve-source', 'sharps', 'flats' ), true ) ? $input['enharmonic_preference'] : $defaults['enharmonic_preference']; $output['print_footer_notice'] = sanitize_textarea_field( $input['print_footer_notice'] ?? '' ); return wp_parse_args( $output, $defaults ); } /** * Get supported public post types. * * @return array */ public function get_supported_post_types() { $post_types = get_post_types( array( 'public' => true, ), 'objects' ); unset( $post_types['attachment'] ); return apply_filters( 'da_plectrum_supported_post_types', $post_types ); } /** * Sanitize selected automatic-processing post types. * * @param mixed $raw_post_types Raw post type values. * @return array */ private function sanitize_post_types( $raw_post_types ) { $selected = is_array( $raw_post_types ) ? $raw_post_types : array(); $allowed = array_keys( $this->get_supported_post_types() ); return array_values( array_intersect( array_map( 'sanitize_key', $selected ), $allowed ) ); } /** * Sanitize the default diagram width. * * @param mixed $value Raw width value. * @return int */ private function sanitize_diagram_width( $value ) { $width = absint( $value ); if ( $width < 12 ) { return 12; } if ( $width > 80 ) { return 80; } return $width; } /** * Sanitize the default song scale. * * @param mixed $value Raw scale value. * @return float */ private function sanitize_song_scale( $value ) { $scale = is_numeric( $value ) ? (float) $value : 1; $scale = max( 0.75, min( 1.75, $scale ) ); return round( $scale, 2 ); } /** * Sanitize the chord prompt font size. * * @param mixed $value Raw font size value. * @return int */ private function sanitize_chord_prompt_font_size( $value ) { $size = absint( $value ); if ( $size < 8 ) { return 8; } if ( $size > 48 ) { return 48; } return $size; } /** * Sanitize spacing values. * * @param mixed $value Raw spacing value. * @param int $max Maximum allowed value. * @return int */ private function sanitize_spacing( $value, $max ) { $spacing = absint( $value ); if ( $spacing > $max ) { return $max; } return $spacing; } /** * Enqueue assets for the plugin settings screen. * * @param string $hook_suffix Current admin page hook suffix. * @return void */ public function enqueue_admin_assets( $hook_suffix ) { if ( $this->page_hook !== $hook_suffix ) { return; } wp_enqueue_style( 'da-plectrum-admin' ); wp_enqueue_script( 'da-plectrum-admin' ); } /** * Get a setting. * * @param string $key Setting key. * @return mixed */ public function get( $key ) { $settings = get_option( DA_PLECTRUM_OPTION_KEY, array() ); $defaults = self::get_default_settings(); return $settings[ $key ] ?? $defaults[ $key ] ?? null; } /** * Render checkbox field. * * @param array $args Field args. * @return void */ public function render_checkbox_field( $args ) { $settings = get_option( DA_PLECTRUM_OPTION_KEY, self::get_default_settings() ); $key = $args['key']; $value = ! empty( $settings[ $key ] ); ?> $args Field args. * @return void */ public function render_select_field( $args ) { $settings = get_option( DA_PLECTRUM_OPTION_KEY, self::get_default_settings() ); $key = $args['key']; $value = $settings[ $key ] ?? ''; ?>

$args Field args. * @return void */ public function render_textarea_field( $args ) { $settings = get_option( DA_PLECTRUM_OPTION_KEY, self::get_default_settings() ); $key = $args['key']; $value = $settings[ $key ] ?? ''; ?>

$args Field args. * @return void */ public function render_number_field( $args ) { $settings = get_option( DA_PLECTRUM_OPTION_KEY, self::get_default_settings() ); $key = $args['key']; $value = $settings[ $key ] ?? ''; ?> min="" max="" step="" class="small-text" />

$args Field args. * @return void */ public function render_post_types_field( $args ) { $settings = get_option( DA_PLECTRUM_OPTION_KEY, self::get_default_settings() ); $key = $args['key']; $selected_types = isset( $settings[ $key ] ) && is_array( $settings[ $key ] ) ? $settings[ $key ] : array(); $post_types = $this->get_supported_post_types(); foreach ( $post_types as $post_type ) : ?>