diff -r 372f2766ea20 -r bf1778c34b9a wp/wp-content/plugins/option-tree/includes/ot-functions-admin.php --- a/wp/wp-content/plugins/option-tree/includes/ot-functions-admin.php Mon Oct 14 18:30:03 2019 +0200 +++ b/wp/wp-content/plugins/option-tree/includes/ot-functions-admin.php Mon Oct 14 18:35:50 2019 +0200 @@ -1,1795 +1,1671 @@ - - * @copyright Copyright (c) 2013, Derek Herman - * @since 2.0 + * @package OptionTree */ -/** - * Registers the Theme Option page - * - * @uses ot_register_settings() - * - * @return void - * - * @access public - * @since 2.1 - */ +if ( ! defined( 'OT_VERSION' ) ) { + exit( 'No direct script access allowed' ); +} + if ( ! function_exists( 'ot_register_theme_options_page' ) ) { - function ot_register_theme_options_page() { - - /* get the settings array */ - $get_settings = get_option( ot_settings_id() ); - - /* sections array */ - $sections = isset( $get_settings['sections'] ) ? $get_settings['sections'] : array(); - - /* settings array */ - $settings = isset( $get_settings['settings'] ) ? $get_settings['settings'] : array(); - - /* contexual_help array */ - $contextual_help = isset( $get_settings['contextual_help'] ) ? $get_settings['contextual_help'] : array(); - - /* build the Theme Options */ - if ( function_exists( 'ot_register_settings' ) && OT_USE_THEME_OPTIONS ) { - - ot_register_settings( array( - array( - 'id' => ot_options_id(), - 'pages' => array( - array( - 'id' => 'ot_theme_options', - 'parent_slug' => apply_filters( 'ot_theme_options_parent_slug', 'themes.php' ), - 'page_title' => apply_filters( 'ot_theme_options_page_title', __( 'Theme Options', 'option-tree' ) ), - 'menu_title' => apply_filters( 'ot_theme_options_menu_title', __( 'Theme Options', 'option-tree' ) ), - 'capability' => $caps = apply_filters( 'ot_theme_options_capability', 'edit_theme_options' ), - 'menu_slug' => apply_filters( 'ot_theme_options_menu_slug', 'ot-theme-options' ), - 'icon_url' => apply_filters( 'ot_theme_options_icon_url', null ), - 'position' => apply_filters( 'ot_theme_options_position', null ), - 'updated_message' => apply_filters( 'ot_theme_options_updated_message', __( 'Theme Options updated.', 'option-tree' ) ), - 'reset_message' => apply_filters( 'ot_theme_options_reset_message', __( 'Theme Options reset.', 'option-tree' ) ), - 'button_text' => apply_filters( 'ot_theme_options_button_text', __( 'Save Changes', 'option-tree' ) ), - 'contextual_help' => apply_filters( 'ot_theme_options_contextual_help', $contextual_help ), - 'sections' => apply_filters( 'ot_theme_options_sections', $sections ), - 'settings' => apply_filters( 'ot_theme_options_settings', $settings ) - ) - ) - ) - ) - ); - - // Filters the options.php to add the minimum user capabilities. - add_filter( 'option_page_capability_' . ot_options_id(), create_function( '$caps', "return '$caps';" ), 999 ); - - } - - } - + /** + * Registers the Theme Option page + * + * @uses ot_register_settings() + * + * @access public + * @since 2.1 + */ + function ot_register_theme_options_page() { + + // Get the settings array. + $get_settings = get_option( ot_settings_id() ); + + // Sections array. + $sections = isset( $get_settings['sections'] ) ? $get_settings['sections'] : array(); + + // Settings array. + $settings = isset( $get_settings['settings'] ) ? $get_settings['settings'] : array(); + + // Contexual help array. + $contextual_help = isset( $get_settings['contextual_help'] ) ? $get_settings['contextual_help'] : array(); + + // Build the Theme Options. + if ( function_exists( 'ot_register_settings' ) && OT_USE_THEME_OPTIONS ) { + + $caps = apply_filters( 'ot_theme_options_capability', 'edit_theme_options' ); + + ot_register_settings( + array( + array( + 'id' => ot_options_id(), + 'pages' => array( + array( + 'id' => 'ot_theme_options', + 'parent_slug' => apply_filters( 'ot_theme_options_parent_slug', 'themes.php' ), + 'page_title' => apply_filters( 'ot_theme_options_page_title', esc_html__( 'Theme Options', 'option-tree' ) ), + 'menu_title' => apply_filters( 'ot_theme_options_menu_title', esc_html__( 'Theme Options', 'option-tree' ) ), + 'capability' => $caps, + 'menu_slug' => apply_filters( 'ot_theme_options_menu_slug', 'ot-theme-options' ), + 'icon_url' => apply_filters( 'ot_theme_options_icon_url', null ), + 'position' => apply_filters( 'ot_theme_options_position', null ), + 'updated_message' => apply_filters( 'ot_theme_options_updated_message', esc_html__( 'Theme Options updated.', 'option-tree' ) ), + 'reset_message' => apply_filters( 'ot_theme_options_reset_message', esc_html__( 'Theme Options reset.', 'option-tree' ) ), + 'button_text' => apply_filters( 'ot_theme_options_button_text', esc_html__( 'Save Changes', 'option-tree' ) ), + 'contextual_help' => apply_filters( 'ot_theme_options_contextual_help', $contextual_help ), + 'sections' => apply_filters( 'ot_theme_options_sections', $sections ), + 'settings' => apply_filters( 'ot_theme_options_settings', $settings ), + ), + ), + ), + ) + ); + + // Filters the options.php to add the minimum user capabilities. + add_filter( + 'option_page_capability_' . ot_options_id(), + function() use ( $caps ) { + return $caps; + }, + 999 + ); + + } + + } } -/** - * Registers the Settings page - * - * @uses ot_register_settings() - * - * @return void - * - * @access public - * @since 2.1 - */ if ( ! function_exists( 'ot_register_settings_page' ) ) { - function ot_register_settings_page() { - global $ot_has_custom_theme_options; - - // Display UI Builder admin notice - if ( OT_SHOW_OPTIONS_UI == true && isset( $_REQUEST['page'] ) && $_REQUEST['page'] == 'ot-settings' && ( $ot_has_custom_theme_options == true || has_action( 'admin_init', 'custom_theme_options' ) || has_action( 'init', 'custom_theme_options' ) ) ) { - - function ot_has_custom_theme_options() { - - echo '

' . __( 'The Theme Options UI Builder is being overridden by a custom file in your theme. Any changes you make via the UI Builder will not be saved.', 'option-tree' ) . '

'; - - } - - add_action( 'admin_notices', 'ot_has_custom_theme_options' ); - - } - - // Create the filterable pages array - $ot_register_pages_array = array( - array( - 'id' => 'ot', - 'page_title' => __( 'OptionTree', 'option-tree' ), - 'menu_title' => __( 'OptionTree', 'option-tree' ), - 'capability' => 'edit_theme_options', - 'menu_slug' => 'ot-settings', - 'icon_url' => null, - 'position' => 61, - 'hidden_page' => true - ), - array( - 'id' => 'settings', - 'parent_slug' => 'ot-settings', - 'page_title' => __( 'Settings', 'option-tree' ), - 'menu_title' => __( 'Settings', 'option-tree' ), - 'capability' => 'edit_theme_options', - 'menu_slug' => 'ot-settings', - 'icon_url' => null, - 'position' => null, - 'updated_message' => __( 'Theme Options updated.', 'option-tree' ), - 'reset_message' => __( 'Theme Options reset.', 'option-tree' ), - 'button_text' => __( 'Save Settings', 'option-tree' ), - 'show_buttons' => false, - 'sections' => array( - array( - 'id' => 'create_setting', - 'title' => __( 'Theme Options UI', 'option-tree' ) - ), - array( - 'id' => 'import', - 'title' => __( 'Import', 'option-tree' ) - ), - array( - 'id' => 'export', - 'title' => __( 'Export', 'option-tree' ) - ), - array( - 'id' => 'layouts', - 'title' => __( 'Layouts', 'option-tree' ) - ) - ), - 'settings' => array( - array( - 'id' => 'theme_options_ui_text', - 'label' => __( 'Theme Options UI Builder', 'option-tree' ), - 'type' => 'theme_options_ui', - 'section' => 'create_setting' - ), - array( - 'id' => 'import_xml_text', - 'label' => __( 'Settings XML', 'option-tree' ), - 'type' => 'import-xml', - 'section' => 'import' - ), - array( - 'id' => 'import_settings_text', - 'label' => __( 'Settings', 'option-tree' ), - 'type' => 'import-settings', - 'section' => 'import' - ), - array( - 'id' => 'import_data_text', - 'label' => __( 'Theme Options', 'option-tree' ), - 'type' => 'import-data', - 'section' => 'import' - ), - array( - 'id' => 'import_layouts_text', - 'label' => __( 'Layouts', 'option-tree' ), - 'type' => 'import-layouts', - 'section' => 'import' - ), - array( - 'id' => 'export_settings_file_text', - 'label' => __( 'Settings PHP File', 'option-tree' ), - 'type' => 'export-settings-file', - 'section' => 'export' - ), - array( - 'id' => 'export_settings_text', - 'label' => __( 'Settings', 'option-tree' ), - 'type' => 'export-settings', - 'section' => 'export' - ), - array( - 'id' => 'export_data_text', - 'label' => __( 'Theme Options', 'option-tree' ), - 'type' => 'export-data', - 'section' => 'export' - ), - array( - 'id' => 'export_layout_text', - 'label' => __( 'Layouts', 'option-tree' ), - 'type' => 'export-layouts', - 'section' => 'export' - ), - array( - 'id' => 'modify_layouts_text', - 'label' => __( 'Layout Management', 'option-tree' ), - 'type' => 'modify-layouts', - 'section' => 'layouts' - ) - ) - ), - array( - 'id' => 'documentation', - 'parent_slug' => 'ot-settings', - 'page_title' => __( 'Documentation', 'option-tree' ), - 'menu_title' => __( 'Documentation', 'option-tree' ), - 'capability' => 'edit_theme_options', - 'menu_slug' => 'ot-documentation', - 'icon_url' => null, - 'position' => null, - 'updated_message' => __( 'Theme Options updated.', 'option-tree' ), - 'reset_message' => __( 'Theme Options reset.', 'option-tree' ), - 'button_text' => __( 'Save Settings', 'option-tree' ), - 'show_buttons' => false, - 'sections' => array( - array( - 'id' => 'creating_options', - 'title' => __( 'Creating Options', 'option-tree' ) - ), - array( - 'id' => 'option_types', - 'title' => __( 'Option Types', 'option-tree' ) - ), - array( - 'id' => 'functions', - 'title' => __( 'Function References', 'option-tree' ) - ), - array( - 'id' => 'theme_mode', - 'title' => __( 'Theme Mode', 'option-tree' ) - ), - array( - 'id' => 'meta_boxes', - 'title' => __( 'Meta Boxes', 'option-tree' ) - ), - array( - 'id' => 'examples', - 'title' => __( 'Code Examples', 'option-tree' ) - ), - array( - 'id' => 'layouts_overview', - 'title' => __( 'Layouts Overview', 'option-tree' ) - ) - ), - 'settings' => array( - array( - 'id' => 'creating_options_text', - 'label' => __( 'Overview of available Theme Option fields.', 'option-tree' ), - 'type' => 'creating-options', - 'section' => 'creating_options' - ), - array( - 'id' => 'option_types_text', - 'label' => __( 'Option types in alphabetical order & hooks to filter them.', 'option-tree' ), - 'type' => 'option-types', - 'section' => 'option_types' - ), - array( - 'id' => 'functions_ot_get_option', - 'label' => __( 'Function Reference:ot_get_option()', 'option-tree' ), - 'type' => 'ot-get-option', - 'section' => 'functions' - ), - array( - 'id' => 'functions_get_option_tree', - 'label' => __( 'Function Reference:get_option_tree()', 'option-tree' ), - 'type' => 'get-option-tree', - 'section' => 'functions' - ), - array( - 'id' => 'theme_mode_text', - 'label' => __( 'Theme Mode', 'option-tree' ), - 'type' => 'theme-mode', - 'section' => 'theme_mode' - ), - array( - 'id' => 'meta_boxes_text', - 'label' => __( 'Meta Boxes', 'option-tree' ), - 'type' => 'meta-boxes', - 'section' => 'meta_boxes' - ), - array( - 'id' => 'example_text', - 'label' => __( 'Code examples for front-end development.', 'option-tree' ), - 'type' => 'examples', - 'section' => 'examples' - ), - array( - 'id' => 'layouts_overview_text', - 'label' => __( 'What\'s a layout anyhow?', 'option-tree' ), - 'type' => 'layouts-overview', - 'section' => 'layouts_overview' - ) - ) - ) - ); - - // Loop over the settings and remove as needed. - foreach( $ot_register_pages_array as $key => $page ) { - - // Remove various options from the Settings UI. - if ( $page['id'] == 'settings' ) { - - // Remove the Theme Options UI - if ( OT_SHOW_OPTIONS_UI == false ) { - - foreach( $page['sections'] as $section_key => $section ) { - if ( $section['id'] == 'create_setting' ) { - unset($ot_register_pages_array[$key]['sections'][$section_key]); - } - } - - foreach( $page['settings'] as $setting_key => $setting ) { - if ( $setting['section'] == 'create_setting' ) { - unset($ot_register_pages_array[$key]['settings'][$setting_key]); - } - } - - } - - // Remove parts of the Imports UI - if ( OT_SHOW_SETTINGS_IMPORT == false ) { - - foreach( $page['settings'] as $setting_key => $setting ) { - if ( $setting['section'] == 'import' && in_array( $setting['id'], array('import_xml_text', 'import_settings_text' ) ) ) { - unset($ot_register_pages_array[$key]['settings'][$setting_key]); - } - } - - } - - // Remove parts of the Export UI - if ( OT_SHOW_SETTINGS_EXPORT == false ) { - - foreach( $page['settings'] as $setting_key => $setting ) { - if ( $setting['section'] == 'export' && in_array( $setting['id'], array('export_settings_file_text', 'export_settings_text' ) ) ) { - unset($ot_register_pages_array[$key]['settings'][$setting_key]); - } - } - - } - - // Remove the Layouts UI - if ( OT_SHOW_NEW_LAYOUT == false ) { - - foreach( $page['sections'] as $section_key => $section ) { - if ( $section['id'] == 'layouts' ) { - unset($ot_register_pages_array[$key]['sections'][$section_key]); - } - } - - foreach( $page['settings'] as $setting_key => $setting ) { - if ( $setting['section'] == 'layouts' ) { - unset($ot_register_pages_array[$key]['settings'][$setting_key]); - } - } - - } - - } - - // Remove the Documentation UI. - if ( OT_SHOW_DOCS == false && $page['id'] == 'documentation' ) { - - unset( $ot_register_pages_array[$key] ); - - } - - } - - $ot_register_pages_array = apply_filters( 'ot_register_pages_array', $ot_register_pages_array ); - - // Register the pages. - ot_register_settings( array( - array( - 'id' => ot_settings_id(), - 'pages' => $ot_register_pages_array - ) - ) - ); - - } - + /** + * Registers the Settings page. + * + * @access public + * @since 2.1 + */ + function ot_register_settings_page() { + global $ot_has_custom_theme_options; + + $custom_options = ( true === $ot_has_custom_theme_options || has_action( 'admin_init', 'custom_theme_options' ) || has_action( 'init', 'custom_theme_options' ) ); + + // Display UI Builder admin notice. + if ( true === OT_SHOW_OPTIONS_UI && isset( $_REQUEST['page'] ) && 'ot-settings' === $_REQUEST['page'] && $custom_options ) { // phpcs:ignore + + /** + * Error message for custom theme options. + */ + function ot_has_custom_theme_options() { + echo '

' . esc_html__( 'The Theme Options UI Builder is being overridden by a custom file in your theme. Any changes you make via the UI Builder will not be saved.', 'option-tree' ) . '

'; + } + + add_action( 'admin_notices', 'ot_has_custom_theme_options' ); + } + + // Create the filterable pages array. + $ot_register_pages_array = array( + array( + 'id' => 'ot', + 'page_title' => esc_html__( 'OptionTree', 'option-tree' ), + 'menu_title' => esc_html__( 'OptionTree', 'option-tree' ), + 'capability' => 'edit_theme_options', + 'menu_slug' => 'ot-settings', + 'icon_url' => null, + 'position' => 61, + 'hidden_page' => true, + ), + array( + 'id' => 'settings', + 'parent_slug' => 'ot-settings', + 'page_title' => esc_html__( 'Settings', 'option-tree' ), + 'menu_title' => esc_html__( 'Settings', 'option-tree' ), + 'capability' => 'edit_theme_options', + 'menu_slug' => 'ot-settings', + 'icon_url' => null, + 'position' => null, + 'updated_message' => esc_html__( 'Theme Options updated.', 'option-tree' ), + 'reset_message' => esc_html__( 'Theme Options reset.', 'option-tree' ), + 'button_text' => esc_html__( 'Save Settings', 'option-tree' ), + 'show_buttons' => false, + 'sections' => array( + array( + 'id' => 'create_setting', + 'title' => esc_html__( 'Theme Options UI', 'option-tree' ), + ), + array( + 'id' => 'import', + 'title' => esc_html__( 'Import', 'option-tree' ), + ), + array( + 'id' => 'export', + 'title' => esc_html__( 'Export', 'option-tree' ), + ), + array( + 'id' => 'layouts', + 'title' => esc_html__( 'Layouts', 'option-tree' ), + ), + ), + 'settings' => array( + array( + 'id' => 'theme_options_ui_text', + 'label' => esc_html__( 'Theme Options UI Builder', 'option-tree' ), + 'type' => 'theme_options_ui', + 'section' => 'create_setting', + ), + array( + 'id' => 'import_settings_text', + 'label' => esc_html__( 'Settings', 'option-tree' ), + 'type' => 'import-settings', + 'section' => 'import', + ), + array( + 'id' => 'import_data_text', + 'label' => esc_html__( 'Theme Options', 'option-tree' ), + 'type' => 'import-data', + 'section' => 'import', + ), + array( + 'id' => 'import_layouts_text', + 'label' => esc_html__( 'Layouts', 'option-tree' ), + 'type' => 'import-layouts', + 'section' => 'import', + ), + array( + 'id' => 'export_settings_file_text', + 'label' => esc_html__( 'Settings PHP File', 'option-tree' ), + 'type' => 'export-settings-file', + 'section' => 'export', + ), + array( + 'id' => 'export_settings_text', + 'label' => esc_html__( 'Settings', 'option-tree' ), + 'type' => 'export-settings', + 'section' => 'export', + ), + array( + 'id' => 'export_data_text', + 'label' => esc_html__( 'Theme Options', 'option-tree' ), + 'type' => 'export-data', + 'section' => 'export', + ), + array( + 'id' => 'export_layout_text', + 'label' => esc_html__( 'Layouts', 'option-tree' ), + 'type' => 'export-layouts', + 'section' => 'export', + ), + array( + 'id' => 'modify_layouts_text', + 'label' => esc_html__( 'Layout Management', 'option-tree' ), + 'type' => 'modify-layouts', + 'section' => 'layouts', + ), + ), + ), + array( + 'id' => 'documentation', + 'parent_slug' => 'ot-settings', + 'page_title' => esc_html__( 'Documentation', 'option-tree' ), + 'menu_title' => esc_html__( 'Documentation', 'option-tree' ), + 'capability' => 'edit_theme_options', + 'menu_slug' => 'ot-documentation', + 'icon_url' => null, + 'position' => null, + 'updated_message' => esc_html__( 'Theme Options updated.', 'option-tree' ), + 'reset_message' => esc_html__( 'Theme Options reset.', 'option-tree' ), + 'button_text' => esc_html__( 'Save Settings', 'option-tree' ), + 'show_buttons' => false, + 'sections' => array( + array( + 'id' => 'creating_options', + 'title' => esc_html__( 'Creating Options', 'option-tree' ), + ), + array( + 'id' => 'option_types', + 'title' => esc_html__( 'Option Types', 'option-tree' ), + ), + array( + 'id' => 'functions', + 'title' => esc_html__( 'Function References', 'option-tree' ), + ), + array( + 'id' => 'theme_mode', + 'title' => esc_html__( 'Theme Mode', 'option-tree' ), + ), + array( + 'id' => 'meta_boxes', + 'title' => esc_html__( 'Meta Boxes', 'option-tree' ), + ), + array( + 'id' => 'examples', + 'title' => esc_html__( 'Code Examples', 'option-tree' ), + ), + array( + 'id' => 'layouts_overview', + 'title' => esc_html__( 'Layouts Overview', 'option-tree' ), + ), + ), + 'settings' => array( + array( + 'id' => 'creating_options_text', + 'label' => esc_html__( 'Overview of available Theme Option fields.', 'option-tree' ), + 'type' => 'creating-options', + 'section' => 'creating_options', + ), + array( + 'id' => 'option_types_text', + 'label' => esc_html__( 'Option types in alphabetical order & hooks to filter them.', 'option-tree' ), + 'type' => 'option-types', + 'section' => 'option_types', + ), + array( + 'id' => 'functions_ot_get_option', + 'label' => esc_html__( 'Function Reference:ot_get_option()', 'option-tree' ), + 'type' => 'ot-get-option', + 'section' => 'functions', + ), + array( + 'id' => 'functions_get_option_tree', + 'label' => esc_html__( 'Function Reference:get_option_tree()', 'option-tree' ), + 'type' => 'get-option-tree', + 'section' => 'functions', + ), + array( + 'id' => 'theme_mode_text', + 'label' => esc_html__( 'Theme Mode', 'option-tree' ), + 'type' => 'theme-mode', + 'section' => 'theme_mode', + ), + array( + 'id' => 'meta_boxes_text', + 'label' => esc_html__( 'Meta Boxes', 'option-tree' ), + 'type' => 'meta-boxes', + 'section' => 'meta_boxes', + ), + array( + 'id' => 'example_text', + 'label' => esc_html__( 'Code examples for front-end development.', 'option-tree' ), + 'type' => 'examples', + 'section' => 'examples', + ), + array( + 'id' => 'layouts_overview_text', + 'label' => esc_html__( 'What\'s a layout anyhow?', 'option-tree' ), + 'type' => 'layouts-overview', + 'section' => 'layouts_overview', + ), + ), + ), + ); + + // Loop over the settings and remove as needed. + foreach ( $ot_register_pages_array as $key => $page ) { + + // Remove various options from the Settings UI. + if ( 'settings' === $page['id'] ) { + + // Remove the Theme Options UI. + if ( false === OT_SHOW_OPTIONS_UI ) { + + foreach ( $page['sections'] as $section_key => $section ) { + if ( 'create_setting' === $section['id'] ) { + unset( $ot_register_pages_array[ $key ]['sections'][ $section_key ] ); + } + } + + foreach ( $page['settings'] as $setting_key => $setting ) { + if ( 'create_setting' === $setting['section'] ) { + unset( $ot_register_pages_array[ $key ]['settings'][ $setting_key ] ); + } + } + } + + // Remove parts of the Imports UI. + if ( false === OT_SHOW_SETTINGS_IMPORT ) { + + foreach ( $page['settings'] as $setting_key => $setting ) { + if ( 'import' === $setting['section'] && in_array( $setting['id'], array( 'import_xml_text', 'import_settings_text' ), true ) ) { + unset( $ot_register_pages_array[ $key ]['settings'][ $setting_key ] ); + } + } + } + + // Remove parts of the Export UI. + if ( false === OT_SHOW_SETTINGS_EXPORT ) { + + foreach ( $page['settings'] as $setting_key => $setting ) { + if ( 'export' === $setting['section'] && in_array( $setting['id'], array( 'export_settings_file_text', 'export_settings_text' ), true ) ) { + unset( $ot_register_pages_array[ $key ]['settings'][ $setting_key ] ); + } + } + } + + // Remove the Layouts UI. + if ( false === OT_SHOW_NEW_LAYOUT ) { + + foreach ( $page['sections'] as $section_key => $section ) { + if ( 'layouts' === $section['id'] ) { + unset( $ot_register_pages_array[ $key ]['sections'][ $section_key ] ); + } + } + + foreach ( $page['settings'] as $setting_key => $setting ) { + if ( 'layouts' === $setting['section'] ) { + unset( $ot_register_pages_array[ $key ]['settings'][ $setting_key ] ); + } + } + } + } + + // Remove the Documentation UI. + if ( false === OT_SHOW_DOCS && 'documentation' === $page['id'] ) { + unset( $ot_register_pages_array[ $key ] ); + } + } + + $ot_register_pages_array = apply_filters( 'ot_register_pages_array', $ot_register_pages_array ); + + // Register the pages. + ot_register_settings( + array( + array( + 'id' => ot_settings_id(), + 'pages' => $ot_register_pages_array, + ), + ) + ); + + } } -/** - * Runs directly after the Theme Options are save. - * - * @return void - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_after_theme_options_save' ) ) { - function ot_after_theme_options_save() { - - $page = isset( $_REQUEST['page'] ) ? $_REQUEST['page'] : ''; - $updated = isset( $_REQUEST['settings-updated'] ) && $_REQUEST['settings-updated'] == 'true' ? true : false; - - /* only execute after the theme options are saved */ - if ( apply_filters( 'ot_theme_options_menu_slug', 'ot-theme-options' ) == $page && $updated ) { - - /* grab a copy of the theme options */ - $options = get_option( ot_options_id() ); - - /* execute the action hook and pass the theme options to it */ - do_action( 'ot_after_theme_options_save', $options ); - - } - - } - + /** + * Runs directly after the Theme Options are save. + * + * @access public + * @since 2.0 + */ + function ot_after_theme_options_save() { + + $page = isset( $_REQUEST['page'] ) ? esc_attr( wp_unslash( $_REQUEST['page'] ) ) : ''; // phpcs:ignore + $updated = isset( $_REQUEST['settings-updated'] ) && true === filter_var( wp_unslash( $_REQUEST['settings-updated'] ), FILTER_VALIDATE_BOOLEAN ); // phpcs:ignore + + // Only execute after the theme options are saved. + if ( apply_filters( 'ot_theme_options_menu_slug', 'ot-theme-options' ) === $page && $updated ) { + + // Grab a copy of the theme options. + $options = get_option( ot_options_id() ); + + // Execute the action hook and pass the theme options to it. + do_action( 'ot_after_theme_options_save', $options ); + } + } } -/** - * Validate the options by type before saving. - * - * This function will run on only some of the option types - * as all of them don't need to be validated, just the - * ones users are going to input data into; because they - * can't be trusted. - * - * @param mixed Setting value - * @param string Setting type - * @param string Setting field ID - * @param string WPML field ID - * @return mixed - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_validate_setting' ) ) { - function ot_validate_setting( $input, $type, $field_id, $wmpl_id = '' ) { - - /* exit early if missing data */ - if ( ! $input || ! $type || ! $field_id ) - return $input; - - $input = apply_filters( 'ot_validate_setting', $input, $type, $field_id ); - - /* WPML Register and Unregister strings */ - if ( ! empty( $wmpl_id ) ) { - - /* Allow filtering on the WPML option types */ - $single_string_types = apply_filters( 'ot_wpml_option_types', array( 'text', 'textarea', 'textarea-simple' ) ); - - if ( in_array( $type, $single_string_types ) ) { - - if ( ! empty( $input ) ) { - - ot_wpml_register_string( $wmpl_id, $input ); - - } else { - - ot_wpml_unregister_string( $wmpl_id ); - - } - - } - - } - - if ( 'background' == $type ) { - - $input['background-color'] = ot_validate_setting( $input['background-color'], 'colorpicker', $field_id ); - - $input['background-image'] = ot_validate_setting( $input['background-image'], 'upload', $field_id ); - - // Loop over array and check for values - foreach( (array) $input as $key => $value ) { - if ( ! empty( $value ) ) { - $has_value = true; - } - } - - // No value; set to empty - if ( ! isset( $has_value ) ) { - $input = ''; - } - - } else if ( 'border' == $type ) { - - // Loop over array and set errors or unset key from array. - foreach( $input as $key => $value ) { - - // Validate width - if ( $key == 'width' && ! empty( $value ) && ! is_numeric( $value ) ) { - - $input[$key] = '0'; - - add_settings_error( 'option-tree', 'invalid_border_width', sprintf( __( 'The %s input field for %s only allows numeric values.', 'option-tree' ), 'width', '' . $field_id . '' ), 'error' ); - - } - - // Validate color - if ( $key == 'color' && ! empty( $value ) ) { - - $input[$key] = ot_validate_setting( $value, 'colorpicker', $field_id ); - - } - - // Unset keys with empty values. - if ( empty( $value ) && strlen( $value ) == 0 ) { - unset( $input[$key] ); - } - - } - - if ( empty( $input ) ) { - $input = ''; - } - - } else if ( 'box-shadow' == $type ) { - - // Validate inset - $input['inset'] = isset( $input['inset'] ) ? 'inset' : ''; - - // Validate offset-x - $input['offset-x'] = ot_validate_setting( $input['offset-x'], 'text', $field_id ); - - // Validate offset-y - $input['offset-y'] = ot_validate_setting( $input['offset-y'], 'text', $field_id ); - - // Validate blur-radius - $input['blur-radius'] = ot_validate_setting( $input['blur-radius'], 'text', $field_id ); - - // Validate spread-radius - $input['spread-radius'] = ot_validate_setting( $input['spread-radius'], 'text', $field_id ); - - // Validate color - $input['color'] = ot_validate_setting( $input['color'], 'colorpicker', $field_id ); - - // Unset keys with empty values. - foreach( $input as $key => $value ) { - if ( empty( $value ) && strlen( $value ) == 0 ) { - unset( $input[$key] ); - } - } - - // Set empty array to empty string. - if ( empty( $input ) ) { - $input = ''; - } - - } else if ( 'colorpicker' == $type ) { - - /* return empty & set error */ - if ( 0 === preg_match( '/^#([a-f0-9]{6}|[a-f0-9]{3})$/i', $input ) && 0 === preg_match( '/^rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9\.]{1,4})\s*\)/i', $input ) ) { - - $input = ''; - - add_settings_error( 'option-tree', 'invalid_hex', sprintf( __( 'The %s Colorpicker only allows valid hexadecimal or rgba values.', 'option-tree' ), '' . $field_id . '' ), 'error' ); - - } - - } else if ( 'colorpicker-opacity' == $type ) { - - // Not allowed - if ( is_array( $input ) ) { - $input = ''; - } - - // Validate color - $input = ot_validate_setting( $input, 'colorpicker', $field_id ); - - } else if ( in_array( $type, array( 'css', 'javascript', 'text', 'textarea', 'textarea-simple' ) ) ) { - - if ( ! current_user_can( 'unfiltered_html' ) && OT_ALLOW_UNFILTERED_HTML == false ) { - - $input = wp_kses_post( $input ); - - } - - } else if ( 'dimension' == $type ) { - - // Loop over array and set error keys or unset key from array. - foreach( $input as $key => $value ) { - if ( ! empty( $value ) && ! is_numeric( $value ) && $key !== 'unit' ) { - $errors[] = $key; - } - if ( empty( $value ) && strlen( $value ) == 0 ) { - unset( $input[$key] ); - } - } - - /* return 0 & set error */ - if ( isset( $errors ) ) { - - foreach( $errors as $error ) { - - $input[$error] = '0'; - - add_settings_error( 'option-tree', 'invalid_dimension_' . $error, sprintf( __( 'The %s input field for %s only allows numeric values.', 'option-tree' ), '' . $error . '', '' . $field_id . '' ), 'error' ); - - } - - } - - if ( empty( $input ) ) { - $input = ''; - } - - } else if ( 'google-fonts' == $type ) { - - unset($input['%key%']); - - // Loop over array and check for values - if ( is_array( $input ) && ! empty( $input ) ) { - $input = array_values( $input ); - } - - // No value; set to empty - if ( empty( $input ) ) { - $input = ''; - } - - } else if ( 'link-color' == $type ) { - - // Loop over array and check for values - if ( is_array( $input ) && ! empty( $input ) ) { - foreach( $input as $key => $value ) { - if ( ! empty( $value ) ) { - $input[$key] = ot_validate_setting( $input[$key], 'colorpicker', $field_id . '-' . $key ); - $has_value = true; - } - } - } - - // No value; set to empty - if ( ! isset( $has_value ) ) { - $input = ''; - } - - } else if ( 'measurement' == $type ) { - - $input[0] = sanitize_text_field( $input[0] ); - - // No value; set to empty - if ( empty( $input[0] ) && strlen( $input[0] ) == 0 && empty( $input[1] ) ) { - $input = ''; - } - - } else if ( 'spacing' == $type ) { - - // Loop over array and set error keys or unset key from array. - foreach( $input as $key => $value ) { - if ( ! empty( $value ) && ! is_numeric( $value ) && $key !== 'unit' ) { - $errors[] = $key; - } - if ( empty( $value ) && strlen( $value ) == 0 ) { - unset( $input[$key] ); - } - } - - /* return 0 & set error */ - if ( isset( $errors ) ) { - - foreach( $errors as $error ) { - - $input[$error] = '0'; - - add_settings_error( 'option-tree', 'invalid_spacing_' . $error, sprintf( __( 'The %s input field for %s only allows numeric values.', 'option-tree' ), '' . $error . '', '' . $field_id . '' ), 'error' ); - - } - - } - - if ( empty( $input ) ) { - $input = ''; - } - - } else if ( 'typography' == $type && isset( $input['font-color'] ) ) { - - $input['font-color'] = ot_validate_setting( $input['font-color'], 'colorpicker', $field_id ); - - // Loop over array and check for values - foreach( $input as $key => $value ) { - if ( ! empty( $value ) ) { - $has_value = true; - } - } - - // No value; set to empty - if ( ! isset( $has_value ) ) { - $input = ''; - } - - } else if ( 'upload' == $type ) { - - if( filter_var( $input, FILTER_VALIDATE_INT ) === FALSE ) { - $input = esc_url_raw( $input ); - } - - } else if ( 'gallery' == $type ) { - - $input = trim( $input ); - - } else if ( 'social-links' == $type ) { - - // Loop over array and check for values, plus sanitize the text field - foreach( (array) $input as $key => $value ) { - if ( ! empty( $value ) && is_array( $value ) ) { - foreach( (array) $value as $item_key => $item_value ) { - if ( ! empty( $item_value ) ) { - $has_value = true; - $input[$key][$item_key] = sanitize_text_field( $item_value ); - } - } - } - } - - // No value; set to empty - if ( ! isset( $has_value ) ) { - $input = ''; - } - - } - - $input = apply_filters( 'ot_after_validate_setting', $input, $type, $field_id ); - - return $input; - - } - + /** + * Validate the options by type before saving. + * + * This function will run on only some of the option types + * as all of them don't need to be validated, just the + * ones users are going to input data into; because they + * can't be trusted. + * + * @param mixed $input Setting value. + * @param string $type Setting type. + * @param string $field_id Setting field ID. + * @param string $wmpl_id WPML field ID. + * @return mixed + * + * @access public + * @since 2.0 + */ + function ot_validate_setting( $input, $type, $field_id, $wmpl_id = '' ) { + + // Exit early if missing data. + if ( ! $input || ! $type || ! $field_id ) { + return $input; + } + + /** + * Filter to modify a setting field value before validation. + * + * This cannot be used to filter the returned value of a custom + * setting type. You must use the `ot_validate_setting_input_safe` + * filter to ensure custom setting types are saved to the database. + * + * @param mixed $input The setting field value. + * @param string $type The setting field type. + * @param string $field_id The setting field ID. + */ + $input = apply_filters( 'ot_validate_setting', $input, $type, $field_id ); + + /** + * Filter to validate a setting field value. + * + * @param mixed $input_safe This is either null, or the filtered input value. + * @param mixed $input The setting field value. + * @param string $type The setting field type. + * @param string $field_id The setting field ID. + */ + $input_safe = apply_filters( 'ot_validate_setting_input_safe', null, $input, $type, $field_id ); + + // The value was filtered and is safe to return. + if ( ! is_null( $input_safe ) ) { + return $input_safe; + } + + /* translators: %1$s: the input id, %2$s: the field id */ + $string_nums = esc_html__( 'The %1$s input field for %2$s only allows numeric values.', 'option-tree' ); + + if ( 'background' === $type ) { + + $input_safe = array(); + + // Loop over array and check for values. + foreach ( (array) $input as $key => $value ) { + if ( 'background-color' === $key ) { + $input_safe[ $key ] = ot_validate_setting( $value, 'colorpicker', $field_id ); + } elseif ( 'background-image' === $key ) { + $input_safe[ $key ] = ot_validate_setting( $value, 'upload', $field_id ); + } else { + $input_safe[ $key ] = sanitize_text_field( $value ); + } + } + } elseif ( 'border' === $type ) { + + $input_safe = array(); + + // Loop over array and set errors or unset key from array. + foreach ( $input as $key => $value ) { + + if ( empty( $value ) ) { + continue; + } + + // Validate width. + if ( 'width' === $key ) { + if ( ! is_numeric( $value ) ) { + add_settings_error( 'option-tree', 'invalid_border_width', sprintf( $string_nums, 'width', '' . $field_id . '' ), 'error' ); + } else { + $input_safe[ $key ] = absint( $value ); + } + } elseif ( 'color' === $key ) { + $input_safe[ $key ] = ot_validate_setting( $value, 'colorpicker', $field_id ); + } else { + $input_safe[ $key ] = sanitize_text_field( $value ); + } + } + } elseif ( 'box-shadow' === $type ) { + + $input_safe = array(); + + // Loop over array and check for values. + foreach ( (array) $input as $key => $value ) { + if ( 'inset' === $key ) { + $input_safe[ $key ] = 'inset'; + } elseif ( 'color' === $key ) { + $input_safe[ $key ] = ot_validate_setting( $value, 'colorpicker', $field_id ); + } else { + $input_safe[ $key ] = sanitize_text_field( $value ); + } + } + } elseif ( 'checkbox' === $type ) { + + $input_safe = array(); + + // Loop over array and check for values. + foreach ( (array) $input as $key => $value ) { + if ( ! empty( $value ) ) { + $input_safe[ $key ] = sanitize_text_field( $value ); + } + } + } elseif ( 'colorpicker' === $type ) { + + $input_safe = ''; + + // Only strings are allowed. + if ( is_string( $input ) ) { + + /* translators: %s: the field id */ + $string_color = esc_html__( 'The %s Colorpicker only allows valid hexadecimal or rgba values depending on the setting type.', 'option-tree' ); + + if ( 0 === preg_match( '/^#([a-f0-9]{6}|[a-f0-9]{3})$/i', $input ) && 0 === preg_match( '/^rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9\.]{1,4})\s*\)/i', $input ) ) { + add_settings_error( 'option-tree', 'invalid_hex_or_rgba', sprintf( $string_color, '' . $field_id . '' ), 'error' ); + } else { + $input_safe = $input; + } + } + } elseif ( 'colorpicker-opacity' === $type ) { + $input_safe = ot_validate_setting( $input, 'colorpicker', $field_id ); + } elseif ( in_array( $type, array( 'category-checkbox', 'custom-post-type-checkbox', 'page-checkbox', 'post-checkbox', 'tag-checkbox', 'taxonomy-checkbox' ), true ) ) { + + $input_safe = array(); + + // Loop over array and check for values. + foreach ( (array) $input as $key => $value ) { + if ( filter_var( $value, FILTER_VALIDATE_INT ) && 0 < $value ) { + $input_safe[ $key ] = absint( $value ); + } + } + } elseif ( in_array( $type, array( 'category-select', 'custom-post-type-select', 'page-select', 'post-select', 'tag-select', 'taxonomy-select' ), true ) ) { + + $input_safe = ''; + + if ( filter_var( $input, FILTER_VALIDATE_INT ) && 0 < $input ) { + $input_safe = absint( $input ); + } + } elseif ( in_array( $type, array( 'css', 'javascript', 'text', 'textarea', 'textarea-simple' ), true ) ) { + if ( ! function_exists( '_filter_wp_kses_post' ) ) { + /** + * Filter the allowed HTML and safe CSS styles. + * + * @since 2.7.2 + * + * @param bool $add Whether to add or remove the filter. + */ + function _filter_wp_kses_post( $add = true ) { + $css_filter = function ( $attr ) { + array_push( $attr, 'display', 'visibility' ); + + $attr = apply_filters( 'ot_safe_style_css', $attr ); + + return $attr; + }; + + $html_filter = function ( $tags, $context ) { + if ( 'post' === $context ) { + if ( current_user_can( 'unfiltered_html' ) || true === OT_ALLOW_UNFILTERED_HTML ) { + $tags['script'] = array_fill_keys( array( 'async', 'charset', 'defer', 'src', 'type' ), true ); + $tags['style'] = array_fill_keys( array( 'media', 'type' ), true ); + $tags['iframe'] = array_fill_keys( array( 'align', 'allowfullscreen', 'class', 'frameborder', 'height', 'id', 'longdesc', 'marginheight', 'marginwidth', 'name', 'sandbox', 'scrolling', 'src', 'srcdoc', 'style', 'width' ), true ); + $tags['noscript'] = true; + + $tags = apply_filters( 'ot_allowed_html', $tags ); + } + } + + return $tags; + }; + + if ( $add ) { + add_filter( 'safe_style_css', $css_filter ); + add_filter( 'wp_kses_allowed_html', $html_filter, 10, 2 ); + } else { + remove_filter( 'safe_style_css', $css_filter ); + remove_filter( 'wp_kses_allowed_html', $html_filter ); + } + } + } + + _filter_wp_kses_post( true ); + $input_safe = wp_kses_post( $input ); + _filter_wp_kses_post( false ); + } elseif ( 'date-picker' === $type || 'date-time-picker' === $type ) { + if ( ! empty( $input ) && (bool) strtotime( $input ) ) { + $input_safe = sanitize_text_field( $input ); + } + } elseif ( 'dimension' === $type ) { + + $input_safe = array(); + + // Loop over array and set errors. + foreach ( $input as $key => $value ) { + if ( ! empty( $value ) ) { + if ( ! is_numeric( $value ) && 'unit' !== $key ) { + add_settings_error( 'option-tree', 'invalid_dimension_' . $key, sprintf( $string_nums, '' . $key . '', '' . $field_id . '' ), 'error' ); + } else { + $input_safe[ $key ] = sanitize_text_field( $value ); + } + } + } + } elseif ( 'gallery' === $type ) { + + $input_safe = ''; + + if ( '' !== trim( $input ) ) { + $input_safe = sanitize_text_field( $input ); + } + } elseif ( 'google-fonts' === $type ) { + + $input_safe = array(); + + // Loop over array. + foreach ( $input as $key => $value ) { + if ( '%key%' === $key ) { + continue; + } + + foreach ( $value as $fk => $fvalue ) { + if ( is_array( $fvalue ) ) { + foreach ( $fvalue as $sk => $svalue ) { + $input_safe[ $key ][ $fk ][ $sk ] = sanitize_text_field( $svalue ); + } + } else { + $input_safe[ $key ][ $fk ] = sanitize_text_field( $fvalue ); + } + } + } + + array_values( $input_safe ); + } elseif ( 'link-color' === $type ) { + + $input_safe = array(); + + // Loop over array and check for values. + if ( is_array( $input ) && ! empty( $input ) ) { + foreach ( $input as $key => $value ) { + if ( ! empty( $value ) ) { + $input_safe[ $key ] = ot_validate_setting( $input[ $key ], 'colorpicker', $field_id . '-' . $key ); + } + } + } + + array_filter( $input_safe ); + } elseif ( 'measurement' === $type ) { + + $input_safe = array(); + + foreach ( $input as $key => $value ) { + if ( ! empty( $value ) ) { + $input_safe[ $key ] = sanitize_text_field( $value ); + } + } + } elseif ( 'numeric-slider' === $type ) { + $input_safe = ''; + + if ( ! empty( $input ) ) { + if ( ! is_numeric( $input ) ) { + add_settings_error( 'option-tree', 'invalid_numeric_slider', sprintf( $string_nums, '' . esc_html__( 'slider', 'option-tree' ) . '', '' . $field_id . '' ), 'error' ); + } else { + $input_safe = sanitize_text_field( $input ); + } + } + } elseif ( 'on-off' === $type ) { + $input_safe = ''; + + if ( ! empty( $input ) ) { + $input_safe = sanitize_text_field( $input ); + } + } elseif ( 'radio' === $type || 'radio-image' === $type || 'select' === $type || 'sidebar-select' === $type ) { + $input_safe = ''; + + if ( ! empty( $input ) ) { + $input_safe = sanitize_text_field( $input ); + } + } elseif ( 'spacing' === $type ) { + + $input_safe = array(); + + // Loop over array and set errors. + foreach ( $input as $key => $value ) { + if ( ! empty( $value ) ) { + if ( ! is_numeric( $value ) && 'unit' !== $key ) { + add_settings_error( 'option-tree', 'invalid_spacing_' . $key, sprintf( $string_nums, '' . $key . '', '' . $field_id . '' ), 'error' ); + } else { + $input_safe[ $key ] = sanitize_text_field( $value ); + } + } + } + } elseif ( 'typography' === $type && isset( $input['font-color'] ) ) { + + $input_safe = array(); + + // Loop over array and check for values. + foreach ( $input as $key => $value ) { + if ( 'font-color' === $key ) { + $input_safe[ $key ] = ot_validate_setting( $value, 'colorpicker', $field_id ); + } else { + $input_safe[ $key ] = sanitize_text_field( $value ); + } + } + } elseif ( 'upload' === $type ) { + + $input_safe = filter_var( $input, FILTER_VALIDATE_INT ); + + if ( false === $input_safe && is_string( $input ) ) { + $input_safe = esc_url_raw( $input ); + } + } elseif ( 'url' === $type ) { + + $input_safe = ''; + + if ( ! empty( $input ) ) { + $input_safe = esc_url_raw( $input ); + } + } else { + + /* translators: %1$s: the calling function, %2$s the filter name, %3$s the option type, %4$s the version number */ + $string_error = esc_html__( 'Notice: %1$s was called incorrectly. All stored data must be filtered through %2$s, the %3$s option type is not using this filter. This is required since version %4$s.', 'option-tree' ); + + // Log a user notice that things have changed since the last version. + add_settings_error( 'option-tree', 'ot_validate_setting_error', sprintf( $string_error, 'ot_validate_setting', 'ot_validate_setting_input_safe', '' . $type . '', '2.7.0' ), 'error' ); + + $input_safe = ''; + + /* + * We don't know what the setting type is, so fallback to `sanitize_textarea_field` + * on all values and do a best-effort sanitize of the user data before saving it. + */ + if ( ! is_object( $input ) ) { + + // Contains an integer, float, string or boolean. + if ( is_scalar( $input ) ) { + $input_safe = sanitize_textarea_field( $input ); + } else { + if ( ! function_exists( '_sanitize_recursive' ) ) { + /** + * Filter the array values recursively. + * + * @param array $values The value to sanitize. + * + * @return array + */ + function _sanitize_recursive( $values = array() ) { + $result = array(); + foreach ( $values as $key => $value ) { + if ( ! is_object( $value ) ) { + if ( is_scalar( $value ) ) { + $result[ $key ] = sanitize_textarea_field( $value ); + } else { + $result[ $key ] = _sanitize_recursive( $value ); + } + } + } + + return $result; + } + } + $input_safe = _sanitize_recursive( $input ); + } + } + } + + // WPML Register and Unregister strings. + if ( ! empty( $wmpl_id ) ) { + + // Allow filtering on the WPML option types. + $single_string_types = apply_filters( 'ot_wpml_option_types', array( 'text', 'textarea', 'textarea-simple' ) ); + + if ( in_array( $type, $single_string_types, true ) ) { + if ( ! empty( $input_safe ) ) { + ot_wpml_register_string( $wmpl_id, $input_safe ); + } else { + ot_wpml_unregister_string( $wmpl_id ); + } + } + } + + /** + * Filter to modify the validated setting field value. + * + * It's important to note that the filter does not have access to + * the original value and can only modify the validated input value. + * This is a breaking change as of version 2.7.0. + * + * @param mixed $input_safe The setting field value. + * @param string $type The setting field type. + * @param string $field_id The setting field ID. + */ + $input_safe = apply_filters( 'ot_after_validate_setting', $input_safe, $type, $field_id ); + + return $input_safe; + } } -/** - * Setup the default admin styles - * - * @return void - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_admin_styles' ) ) { - function ot_admin_styles() { - global $wp_styles, $post; - - /* execute styles before actions */ - do_action( 'ot_admin_styles_before' ); - - /* load WP colorpicker */ - wp_enqueue_style( 'wp-color-picker' ); - - /* load admin styles */ - wp_enqueue_style( 'ot-admin-css', OT_URL . 'assets/css/ot-admin.css', false, OT_VERSION ); - - /* load the RTL stylesheet */ - $wp_styles->add_data( 'ot-admin-css','rtl', true ); - - /* Remove styles added by the Easy Digital Downloads plugin */ - if ( isset( $post->post_type ) && $post->post_type == 'post' ) - wp_dequeue_style( 'jquery-ui-css' ); - - /** - * Filter the screen IDs used to dequeue `jquery-ui-css`. - * - * @since 2.5.0 - * - * @param array $screen_ids An array of screen IDs. - */ - $screen_ids = apply_filters( 'ot_dequeue_jquery_ui_css_screen_ids', array( - 'toplevel_page_ot-settings', - 'optiontree_page_ot-documentation', - 'appearance_page_ot-theme-options' - ) ); - - /* Remove styles added by the WP Review plugin and any custom pages added through filtering */ - if ( in_array( get_current_screen()->id, $screen_ids ) ) { - wp_dequeue_style( 'plugin_name-admin-ui-css' ); - wp_dequeue_style( 'jquery-ui-css' ); - } - - /* execute styles after actions */ - do_action( 'ot_admin_styles_after' ); - - } - + /** + * Setup the default admin styles + * + * @access public + * @since 2.0 + */ + function ot_admin_styles() { + global $wp_styles, $post; + + // Execute styles before actions. + do_action( 'ot_admin_styles_before' ); + + // Load WP colorpicker. + wp_enqueue_style( 'wp-color-picker' ); + + // Load admin styles. + wp_enqueue_style( 'ot-admin-css', OT_URL . 'assets/css/ot-admin.css', false, OT_VERSION ); + + // Load the RTL stylesheet. + $wp_styles->add_data( 'ot-admin-css', 'rtl', true ); + + // Remove styles added by the Easy Digital Downloads plugin. + if ( isset( $post->post_type ) && 'post' === $post->post_type ) { + wp_dequeue_style( 'jquery-ui-css' ); + } + + /** + * Filter the screen IDs used to dequeue `jquery-ui-css`. + * + * @since 2.5.0 + * + * @param array $screen_ids An array of screen IDs. + */ + $screen_ids = apply_filters( + 'ot_dequeue_jquery_ui_css_screen_ids', + array( + 'toplevel_page_ot-settings', + 'optiontree_page_ot-documentation', + 'appearance_page_ot-theme-options', + ) + ); + + // Remove styles added by the WP Review plugin and any custom pages added through filtering. + if ( in_array( get_current_screen()->id, $screen_ids, true ) ) { + wp_dequeue_style( 'plugin_name-admin-ui-css' ); + wp_dequeue_style( 'jquery-ui-css' ); + } + + // Execute styles after actions. + do_action( 'ot_admin_styles_after' ); + } } -/** - * Setup the default admin scripts - * - * @uses add_thickbox() Include Thickbox for file uploads - * @uses wp_enqueue_script() Add OptionTree scripts - * @uses wp_localize_script() Used to include arbitrary Javascript data - * - * @return void - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_admin_scripts' ) ) { - function ot_admin_scripts() { - - /* execute scripts before actions */ - do_action( 'ot_admin_scripts_before' ); - - if ( function_exists( 'wp_enqueue_media' ) ) { - /* WP 3.5 Media Uploader */ - wp_enqueue_media(); - } else { - /* Legacy Thickbox */ - add_thickbox(); - } - - /* load jQuery-ui slider */ - wp_enqueue_script( 'jquery-ui-slider' ); - - /* load jQuery-ui datepicker */ - wp_enqueue_script( 'jquery-ui-datepicker' ); - - /* load WP colorpicker */ - wp_enqueue_script( 'wp-color-picker' ); - - /* load Ace Editor for CSS Editing */ - wp_enqueue_script( 'ace-editor', 'https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/ace.js', null, '1.1.3' ); - - /* load jQuery UI timepicker addon */ - wp_enqueue_script( 'jquery-ui-timepicker', OT_URL . 'assets/js/vendor/jquery/jquery-ui-timepicker.js', array( 'jquery', 'jquery-ui-slider', 'jquery-ui-datepicker' ), '1.4.3' ); - - /* load the post formats */ - if ( OT_META_BOXES == true && OT_POST_FORMATS == true ) { - wp_enqueue_script( 'ot-postformats', OT_URL . 'assets/js/ot-postformats.js', array( 'jquery' ), '1.0.1' ); - } - - /* load all the required scripts */ - wp_enqueue_script( 'ot-admin-js', OT_URL . 'assets/js/ot-admin.js', array( 'jquery', 'jquery-ui-tabs', 'jquery-ui-sortable', 'jquery-ui-slider', 'wp-color-picker', 'ace-editor', 'jquery-ui-datepicker', 'jquery-ui-timepicker' ), OT_VERSION ); - - /* create localized JS array */ - $localized_array = array( - 'ajax' => admin_url( 'admin-ajax.php' ), - 'nonce' => wp_create_nonce( 'option_tree' ), - 'upload_text' => apply_filters( 'ot_upload_text', __( 'Send to OptionTree', 'option-tree' ) ), - 'remove_media_text' => __( 'Remove Media', 'option-tree' ), - 'reset_agree' => __( 'Are you sure you want to reset back to the defaults?', 'option-tree' ), - 'remove_no' => __( 'You can\'t remove this! But you can edit the values.', 'option-tree' ), - 'remove_agree' => __( 'Are you sure you want to remove this?', 'option-tree' ), - 'activate_layout_agree' => __( 'Are you sure you want to activate this layout?', 'option-tree' ), - 'setting_limit' => __( 'Sorry, you can\'t have settings three levels deep.', 'option-tree' ), - 'delete' => __( 'Delete Gallery', 'option-tree' ), - 'edit' => __( 'Edit Gallery', 'option-tree' ), - 'create' => __( 'Create Gallery', 'option-tree' ), - 'confirm' => __( 'Are you sure you want to delete this Gallery?', 'option-tree' ), - 'date_current' => __( 'Today', 'option-tree' ), - 'date_time_current' => __( 'Now', 'option-tree' ), - 'date_close' => __( 'Close', 'option-tree' ), - 'replace' => __( 'Featured Image', 'option-tree' ), - 'with' => __( 'Image', 'option-tree' ) - ); - - /* localized script attached to 'option_tree' */ - wp_localize_script( 'ot-admin-js', 'option_tree', $localized_array ); - - /* execute scripts after actions */ - do_action( 'ot_admin_scripts_after' ); - - } - + /** + * Setup the default admin scripts. + * + * @uses add_thickbox() Include Thickbox for file uploads. + * @uses wp_enqueue_script() Add OptionTree scripts. + * @uses wp_localize_script() Used to include arbitrary Javascript data. + * + * @access public + * @since 2.0 + */ + function ot_admin_scripts() { + + // Execute scripts before actions. + do_action( 'ot_admin_scripts_before' ); + + if ( function_exists( 'wp_enqueue_media' ) ) { + // WP 3.5 Media Uploader. + wp_enqueue_media(); + } else { + // Legacy Thickbox. + add_thickbox(); + } + + // Load jQuery-ui slider. + wp_enqueue_script( 'jquery-ui-slider' ); + + // Load jQuery-ui datepicker. + wp_enqueue_script( 'jquery-ui-datepicker' ); + + // Load WP colorpicker. + wp_enqueue_script( 'wp-color-picker' ); + + // Load Ace Editor for CSS Editing. + wp_enqueue_script( 'ace-editor', 'https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/ace.js', null, '1.1.3', false ); + + // Load jQuery UI timepicker addon. + wp_enqueue_script( 'jquery-ui-timepicker', OT_URL . 'assets/js/vendor/jquery/jquery-ui-timepicker.js', array( 'jquery', 'jquery-ui-slider', 'jquery-ui-datepicker' ), '1.4.3', false ); + + // Load the post formats. + if ( true === OT_META_BOXES && true === OT_POST_FORMATS ) { + wp_enqueue_script( 'ot-postformats', OT_URL . 'assets/js/ot-postformats.js', array( 'jquery' ), '1.0.1', false ); + } + + // Load all the required scripts. + wp_enqueue_script( 'ot-admin-js', OT_URL . 'assets/js/ot-admin.js', array( 'jquery', 'jquery-ui-tabs', 'jquery-ui-sortable', 'jquery-ui-slider', 'wp-color-picker', 'ace-editor', 'jquery-ui-datepicker', 'jquery-ui-timepicker' ), OT_VERSION, false ); + + // Create localized JS array. + $localized_array = array( + 'ajax' => admin_url( 'admin-ajax.php' ), + 'nonce' => wp_create_nonce( 'option_tree' ), + 'upload_text' => apply_filters( 'ot_upload_text', __( 'Send to OptionTree', 'option-tree' ) ), + 'remove_media_text' => esc_html__( 'Remove Media', 'option-tree' ), + 'reset_agree' => esc_html__( 'Are you sure you want to reset back to the defaults?', 'option-tree' ), + 'remove_no' => esc_html__( 'You can\'t remove this! But you can edit the values.', 'option-tree' ), + 'remove_agree' => esc_html__( 'Are you sure you want to remove this?', 'option-tree' ), + 'activate_layout_agree' => esc_html__( 'Are you sure you want to activate this layout?', 'option-tree' ), + 'setting_limit' => esc_html__( 'Sorry, you can\'t have settings three levels deep.', 'option-tree' ), + 'delete' => esc_html__( 'Delete Gallery', 'option-tree' ), + 'edit' => esc_html__( 'Edit Gallery', 'option-tree' ), + 'create' => esc_html__( 'Create Gallery', 'option-tree' ), + 'confirm' => esc_html__( 'Are you sure you want to delete this Gallery?', 'option-tree' ), + 'date_current' => esc_html__( 'Today', 'option-tree' ), + 'date_time_current' => esc_html__( 'Now', 'option-tree' ), + 'date_close' => esc_html__( 'Close', 'option-tree' ), + 'replace' => esc_html__( 'Featured Image', 'option-tree' ), + 'with' => esc_html__( 'Image', 'option-tree' ), + ); + + // Localized script attached to 'option_tree'. + wp_localize_script( 'ot-admin-js', 'option_tree', $localized_array ); + + // Execute scripts after actions. + do_action( 'ot_admin_scripts_after' ); + } } -/** - * Returns the ID of a custom post type by post_title. - * - * @uses get_results() - * - * @return int - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_get_media_post_ID' ) ) { - function ot_get_media_post_ID() { - - // Option ID - $option_id = 'ot_media_post_ID'; - - // Get the media post ID - $post_ID = get_option( $option_id, false ); - - // Add $post_ID to the DB - if ( $post_ID === false || empty( $post_ID ) ) { - global $wpdb; - - // Get the media post ID - $post_ID = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE `post_title` = 'Media' AND `post_type` = 'option-tree' AND `post_status` = 'private'" ); - - // Add to the DB - if ( $post_ID !== null ) - update_option( $option_id, $post_ID ); - - } - - return $post_ID; - - } - + /** + * Returns the ID of a custom post type by post_title. + * + * @return int + * + * @access public + * @since 2.0 + * @updated 2.7.0 + */ + function ot_get_media_post_ID() { // phpcs:ignore + + // Option ID. + $option_id = 'ot_media_post_ID'; + + // Get the media post ID. + $post_ID = get_option( $option_id, false ); + + // Add $post_ID to the DB. + if ( false === $post_ID || empty( $post_ID ) || ! is_integer( $post_ID ) ) { + global $wpdb; + + // Get the media post ID. + $post_ID = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts p WHERE p.post_title = %s AND p.post_type = %s AND p.post_status = %s", 'Media', 'option-tree', 'private' ) ); // phpcs:ignore + + // Add to the DB. + if ( null !== $post_ID && 0 < $post_ID ) { + update_option( $option_id, $post_ID ); + } else { + $post_ID = 0; + } + } + + return $post_ID; + } } -/** - * Register custom post type & create the media post used to attach images. - * - * @uses get_results() - * - * @return void - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_create_media_post' ) ) { - - function ot_create_media_post() { - - $regsiter_post_type = 'register_' . 'post_type'; - $regsiter_post_type( 'option-tree', array( - 'labels' => array( 'name' => __( 'Option Tree', 'option-tree' ) ), - 'public' => false, - 'show_ui' => false, - 'capability_type' => 'post', - 'exclude_from_search' => true, - 'hierarchical' => false, - 'rewrite' => false, - 'supports' => array( 'title', 'editor' ), - 'can_export' => false, - 'show_in_nav_menus' => false - ) ); - - /* look for custom page */ - $post_id = ot_get_media_post_ID(); - - /* no post exists */ - if ( $post_id == 0 ) { - - /* create post object */ - $_p = array(); - $_p['post_title'] = 'Media'; - $_p['post_name'] = 'media'; - $_p['post_status'] = 'private'; - $_p['post_type'] = 'option-tree'; - $_p['comment_status'] = 'closed'; - $_p['ping_status'] = 'closed'; - - /* insert the post into the database */ - wp_insert_post( $_p ); - - } - - } - + + /** + * Register custom post type & create the media post used to attach images. + * + * @access public + * @since 2.0 + */ + function ot_create_media_post() { + + register_post_type( + 'option-tree', + array( + 'labels' => array( 'name' => esc_html__( 'Option Tree', 'option-tree' ) ), + 'public' => false, + 'show_ui' => false, + 'capability_type' => 'post', + 'exclude_from_search' => true, + 'hierarchical' => false, + 'rewrite' => false, + 'supports' => array( 'title', 'editor' ), + 'can_export' => false, + 'show_in_nav_menus' => false, + ) + ); + + // Look for custom page. + $post_id = ot_get_media_post_ID(); + + // No post exists. + if ( 0 === $post_id ) { + + // Insert the post into the database. + wp_insert_post( + array( + 'post_title' => 'Media', + 'post_name' => 'media', + 'post_status' => 'private', + 'post_type' => 'option-tree', + 'comment_status' => 'closed', + 'ping_status' => 'closed', + ) + ); + } + } } -/** - * Setup default settings array. - * - * @return void - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_default_settings' ) ) { - function ot_default_settings() { - global $wpdb; - - if ( ! get_option( ot_settings_id() ) ) { - - $section_count = 0; - $settings_count = 0; - $settings = array(); - $table_name = $wpdb->prefix . 'option_tree'; - - if ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $table_name ) ) == $table_name && $old_settings = $wpdb->get_results( "SELECT * FROM $table_name ORDER BY item_sort ASC" ) ) { - - foreach ( $old_settings as $setting ) { - - /* heading is a section now */ - if ( $setting->item_type == 'heading' ) { - - /* add section to the sections array */ - $settings['sections'][$section_count]['id'] = $setting->item_id; - $settings['sections'][$section_count]['title'] = $setting->item_title; - - /* save the last section id to use in creating settings */ - $section = $setting->item_id; - - /* increment the section count */ - $section_count++; - - } else { - - /* add setting to the settings array */ - $settings['settings'][$settings_count]['id'] = $setting->item_id; - $settings['settings'][$settings_count]['label'] = $setting->item_title; - $settings['settings'][$settings_count]['desc'] = $setting->item_desc; - $settings['settings'][$settings_count]['section'] = $section; - $settings['settings'][$settings_count]['type'] = ot_map_old_option_types( $setting->item_type ); - $settings['settings'][$settings_count]['std'] = ''; - $settings['settings'][$settings_count]['class'] = ''; - - /* textarea rows */ - $rows = ''; - if ( in_array( $settings['settings'][$settings_count]['type'], array( 'css', 'javascript', 'textarea' ) ) ) { - if ( (int) $setting->item_options > 0 ) { - $rows = (int) $setting->item_options; - } else { - $rows = 15; - } - } - $settings['settings'][$settings_count]['rows'] = $rows; - - /* post type */ - $post_type = ''; - if ( in_array( $settings['settings'][$settings_count]['type'], array( 'custom-post-type-select', 'custom-post-type-checkbox' ) ) ) { - if ( '' != $setting->item_options ) { - $post_type = $setting->item_options; - } else { - $post_type = 'post'; - } - } - $settings['settings'][$settings_count]['post_type'] = $post_type; - - /* choices */ - $choices = array(); - if ( in_array( $settings['settings'][$settings_count]['type'], array( 'checkbox', 'radio', 'select' ) ) ) { - if ( '' != $setting->item_options ) { - $choices = ot_convert_string_to_array( $setting->item_options ); - } - } - $settings['settings'][$settings_count]['choices'] = $choices; - - $settings_count++; - } - - } - - /* make sure each setting has a section just incase */ - if ( isset( $settings['sections'] ) && isset( $settings['settings'] ) ) { - foreach( $settings['settings'] as $k => $setting ) { - if ( '' == $setting['section'] ) { - $settings['settings'][$k]['section'] = $settings['sections'][0]['id']; - } - } - } - - } - - /* if array if not properly formed create fallback settings array */ - if ( ! isset( $settings['sections'] ) || ! isset( $settings['settings'] ) ) { - - $settings = array( - 'sections' => array( - array( - 'id' => 'general', - 'title' => __( 'General', 'option-tree' ) - ) - ), - 'settings' => array( - array( - 'id' => 'sample_text', - 'label' => __( 'Sample Text Field Label', 'option-tree' ), - 'desc' => __( 'Description for the sample text field.', 'option-tree' ), - 'section' => 'general', - 'type' => 'text', - 'std' => '', - 'class' => '', - 'rows' => '', - 'post_type' => '', - 'choices' => array() - ) - ) - ); - - } - - /* update the settings array */ - update_option( ot_settings_id(), $settings ); - - /* get option tree array */ - $options = get_option( ot_options_id() ); - - /* validate options */ - if ( is_array( $options ) ) { - - foreach( $settings['settings'] as $setting ) { - - if ( isset( $options[$setting['id']] ) ) { - - $content = ot_stripslashes( $options[$setting['id']] ); - - $options[$setting['id']] = ot_validate_setting( $content, $setting['type'], $setting['id'] ); - - } - - } - - /* execute the action hook and pass the theme options to it */ - do_action( 'ot_before_theme_options_save', $options ); - - /* update the option tree array */ - update_option( ot_options_id(), $options ); - - } - - } - - } - + /** + * Setup default settings array. + * + * @access public + * @since 2.0 + */ + function ot_default_settings() { + global $wpdb; + + if ( ! get_option( ot_settings_id() ) ) { + + $section_count = 0; + $settings_count = 0; + $settings = array(); + $table_name = $wpdb->prefix . 'option_tree'; + + $find_table = wp_cache_get( 'find_table', 'option_tree' ); + if ( false === $find_table ) { + $find_table = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) ); // phpcs:ignore + wp_cache_set( 'find_table', $find_table, 'option_tree', 86400 ); + } + + if ( $find_table === $table_name ) { + + $old_settings = wp_cache_get( 'old_settings', 'option_tree' ); + if ( false === $old_settings ) { + $old_settings = $wpdb->get_results( "SELECT * FROM ${table_name} ORDER BY item_sort ASC" ); // phpcs:ignore + wp_cache_set( 'old_settings', $old_settings, 'option_tree', 86400 ); + } + + if ( ! $old_settings ) { + return; + } + + foreach ( $old_settings as $setting ) { + + // Heading is a section now. + if ( 'heading' === $setting->item_type ) { + + // Add section to the sections array. + $settings['sections'][ $section_count ]['id'] = $setting->item_id; + $settings['sections'][ $section_count ]['title'] = $setting->item_title; + + // Ssave the last section id to use in creating settings. + $section = $setting->item_id; + + // Increment the section count. + $section_count++; + + } else { + + // Add setting to the settings array. + $settings['settings'][ $settings_count ]['id'] = $setting->item_id; + $settings['settings'][ $settings_count ]['label'] = $setting->item_title; + $settings['settings'][ $settings_count ]['desc'] = $setting->item_desc; + $settings['settings'][ $settings_count ]['section'] = $section; + $settings['settings'][ $settings_count ]['type'] = ot_map_old_option_types( $setting->item_type ); + $settings['settings'][ $settings_count ]['std'] = ''; + $settings['settings'][ $settings_count ]['class'] = ''; + + // Textarea rows. + $rows = ''; + if ( in_array( $settings['settings'][ $settings_count ]['type'], array( 'css', 'javascript', 'textarea' ), true ) ) { + if ( (int) $setting->item_options > 0 ) { + $rows = (int) $setting->item_options; + } else { + $rows = 15; + } + } + $settings['settings'][ $settings_count ]['rows'] = $rows; + + // Post type. + $post_type = ''; + if ( in_array( $settings['settings'][ $settings_count ]['type'], array( 'custom-post-type-select', 'custom-post-type-checkbox' ), true ) ) { + if ( '' !== $setting->item_options ) { + $post_type = $setting->item_options; + } else { + $post_type = 'post'; + } + } + $settings['settings'][ $settings_count ]['post_type'] = $post_type; + + // Cchoices. + $choices = array(); + if ( in_array( $settings['settings'][ $settings_count ]['type'], array( 'checkbox', 'radio', 'select' ), true ) ) { + if ( '' !== $setting->item_options ) { + $choices = ot_convert_string_to_array( $setting->item_options ); + } + } + $settings['settings'][ $settings_count ]['choices'] = $choices; + + $settings_count++; + } + } + + // Make sure each setting has a section just in case. + if ( isset( $settings['sections'] ) && isset( $settings['settings'] ) ) { + foreach ( $settings['settings'] as $k => $setting ) { + if ( '' === $setting['section'] ) { + $settings['settings'][ $k ]['section'] = $settings['sections'][0]['id']; + } + } + } + } + + // If array if not properly formed create fallback settings array. + if ( ! isset( $settings['sections'] ) || ! isset( $settings['settings'] ) ) { + + $settings = array( + 'sections' => array( + array( + 'id' => 'general', + 'title' => esc_html__( 'General', 'option-tree' ), + ), + ), + 'settings' => array( + array( + 'id' => 'sample_text', + 'label' => esc_html__( 'Sample Text Field Label', 'option-tree' ), + 'desc' => esc_html__( 'Description for the sample text field.', 'option-tree' ), + 'section' => 'general', + 'type' => 'text', + 'std' => '', + 'class' => '', + 'rows' => '', + 'post_type' => '', + 'choices' => array(), + ), + ), + ); + } + + // Update the settings array. + update_option( ot_settings_id(), $settings ); + + // Get option tree array. + $options = get_option( ot_options_id() ); + + $options_safe = array(); + + // Validate options. + if ( is_array( $options ) ) { + + foreach ( $settings['settings'] as $setting ) { + if ( isset( $options[ $setting['id'] ] ) ) { + $options_safe[ $setting['id'] ] = ot_validate_setting( wp_unslash( $options[ $setting['id'] ] ), $setting['type'], $setting['id'] ); + } + } + + // Execute the action hook and pass the theme options to it. + do_action( 'ot_before_theme_options_save', $options_safe ); + + // Update the option tree array. + update_option( ot_options_id(), $options_safe ); + } + } + } } -/** - * Helper function to update the CSS option type after save. - * - * @return void - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_save_css' ) ) { - function ot_save_css( $options ) { - - /* grab a copy of the settings */ - $settings = get_option( ot_settings_id() ); - - /* has settings */ - if ( isset( $settings['settings'] ) ) { - - /* loop through sections and insert CSS when needed */ - foreach( $settings['settings'] as $k => $setting ) { - - /* is the CSS option type */ - if ( isset( $setting['type'] ) && 'css' == $setting['type'] ) { - - /* insert CSS into dynamic.css */ - if ( isset( $options[$setting['id']] ) && '' !== $options[$setting['id']] ) { - - ot_insert_css_with_markers( $setting['id'], $options[$setting['id']] ); - - /* remove old CSS from dynamic.css */ - } else { - - ot_remove_old_css( $setting['id'] ); - - } - - } - - } - - } - - } - + /** + * Helper function to update the CSS option type after save. + * + * This function is called during the `ot_after_theme_options_save` hook, + * which is passed the currently stored options array. + * + * @param array $options The current stored options array. + * + * @access public + * @since 2.0 + */ + function ot_save_css( $options ) { + + // Grab a copy of the settings. + $settings = get_option( ot_settings_id() ); + + // Has settings. + if ( isset( $settings['settings'] ) ) { + + // Loop through sections and insert CSS when needed. + foreach ( $settings['settings'] as $k => $setting ) { + + // Is the CSS option type. + if ( isset( $setting['type'] ) && 'css' === $setting['type'] ) { + + // Insert CSS into dynamic.css. + if ( isset( $options[ $setting['id'] ] ) && '' !== $options[ $setting['id'] ] ) { + ot_insert_css_with_markers( $setting['id'], $options[ $setting['id'] ] ); + + // Remove old CSS from dynamic.css. + } else { + ot_remove_old_css( $setting['id'] ); + } + } + } + } + } } - -/** - * Helper function to load filters for XML mime type. - * - * @return void - * - * @access public - * @since 2.0 - */ -if ( ! function_exists( 'ot_add_xml_to_upload_filetypes' ) ) { - - function ot_add_xml_to_upload_filetypes() { - - add_filter( 'upload_mimes', 'ot_upload_mimes' ); - add_filter( 'wp_mime_type_icon', 'ot_xml_mime_type_icon', 10, 2 ); - - } - -} - -/** - * Filter 'upload_mimes' and add xml. - * - * @param array $mimes An array of valid upload mime types - * @return array - * - * @access public - * @since 2.0 - */ -if ( ! function_exists( 'ot_upload_mimes' ) ) { - - function ot_upload_mimes( $mimes ) { - - $mimes['xml'] = 'application/xml'; - - return $mimes; - - } - -} - -/** - * Filters 'wp_mime_type_icon' and have xml display as a document. - * - * @param string $icon The mime icon - * @param string $mime The mime type - * @return string - * - * @access public - * @since 2.0 - */ -if ( ! function_exists( 'ot_xml_mime_type_icon' ) ) { - - function ot_xml_mime_type_icon( $icon, $mime ) { - - if ( $mime == 'application/xml' || $mime == 'text/xml' ) - return wp_mime_type_icon( 'document' ); - - return $icon; - - } - -} - -/** - * Import before the screen is displayed. - * - * @return void - * - * @access public - * @since 2.0 - */ + if ( ! function_exists( 'ot_import' ) ) { - function ot_import() { - - /* check and verify import xml nonce */ - if ( isset( $_POST['import_xml_nonce'] ) && wp_verify_nonce( $_POST['import_xml_nonce'], 'import_xml_form' ) ) { - - /* import input value */ - $file = isset( $_POST['import_xml'] ) ? esc_url( $_POST['import_xml'] ) : ''; - - /* validate xml file */ - if ( preg_match( "/(.xml)$/i", $file ) && class_exists( 'SimpleXMLElement' ) ) { - - $settings = ot_import_xml( $file ); - - } - - /* default message */ - $message = 'failed'; - - /* cleanup, save, & show success message */ - if ( isset( $settings ) && ! empty( $settings ) ) { - - /* delete file */ - if ( $file ) { - global $wpdb; - $attachmentid = $wpdb->get_var( "SELECT ID FROM {$wpdb->posts} WHERE guid='$file'" ); - wp_delete_attachment( $attachmentid, true ); - } - - /* update settings */ - update_option( ot_settings_id(), $settings ); - - /* set message */ - $message = 'success'; - - } - - /* redirect */ - wp_redirect( esc_url_raw( add_query_arg( array( 'action' => 'import-xml', 'message' => $message ), $_POST['_wp_http_referer'] ) ) ); - exit; - - } - - /* check and verify import settings nonce */ - if ( isset( $_POST['import_settings_nonce'] ) && wp_verify_nonce( $_POST['import_settings_nonce'], 'import_settings_form' ) ) { - - /* textarea value */ - $textarea = isset( $_POST['import_settings'] ) ? unserialize( ot_decode( $_POST['import_settings'] ) ) : ''; - - /* default message */ - $message = 'failed'; - - /* is array: save & show success message */ - if ( is_array( $textarea ) ) { - update_option( ot_settings_id(), $textarea ); - $message = 'success'; - } - - /* redirect */ - wp_redirect( esc_url_raw( add_query_arg( array( 'action' => 'import-settings', 'message' => $message ), $_POST['_wp_http_referer'] ) ) ); - exit; - - } - - /* check and verify import theme options data nonce */ - if ( isset( $_POST['import_data_nonce'] ) && wp_verify_nonce( $_POST['import_data_nonce'], 'import_data_form' ) ) { - - /* default message */ - $message = 'failed'; - - /* textarea value */ - $options = isset( $_POST['import_data'] ) ? unserialize( ot_decode( $_POST['import_data'] ) ) : ''; - - /* get settings array */ - $settings = get_option( ot_settings_id() ); - - /* has options */ - if ( is_array( $options ) ) { - - /* validate options */ - if ( is_array( $settings ) ) { - - foreach( $settings['settings'] as $setting ) { - - if ( isset( $options[$setting['id']] ) ) { - - $content = ot_stripslashes( $options[$setting['id']] ); - - $options[$setting['id']] = ot_validate_setting( $content, $setting['type'], $setting['id'] ); - - } - - } - - } - - /* execute the action hook and pass the theme options to it */ - do_action( 'ot_before_theme_options_save', $options ); - - /* update the option tree array */ - update_option( ot_options_id(), $options ); - - $message = 'success'; - - } - - /* redirect accordingly */ - wp_redirect( esc_url_raw( add_query_arg( array( 'action' => 'import-data', 'message' => $message ), $_POST['_wp_http_referer'] ) ) ); - exit; - - } - - /* check and verify import layouts nonce */ - if ( isset( $_POST['import_layouts_nonce'] ) && wp_verify_nonce( $_POST['import_layouts_nonce'], 'import_layouts_form' ) ) { - - /* default message */ - $message = 'failed'; - - /* textarea value */ - $layouts = isset( $_POST['import_layouts'] ) ? unserialize( ot_decode( $_POST['import_layouts'] ) ) : ''; - - /* get settings array */ - $settings = get_option( ot_settings_id() ); - - /* has layouts */ - if ( is_array( $layouts ) ) { - - /* validate options */ - if ( is_array( $settings ) ) { - - foreach( $layouts as $key => $value ) { - - if ( $key == 'active_layout' ) - continue; - - $options = unserialize( ot_decode( $value ) ); - - foreach( $settings['settings'] as $setting ) { - - if ( isset( $options[$setting['id']] ) ) { - - $content = ot_stripslashes( $options[$setting['id']] ); - - $options[$setting['id']] = ot_validate_setting( $content, $setting['type'], $setting['id'] ); - - } - - } - - $layouts[$key] = ot_encode( serialize( $options ) ); - - } - - } - - /* update the option tree array */ - if ( isset( $layouts['active_layout'] ) ) { - - $new_options = unserialize( ot_decode( $layouts[$layouts['active_layout']] ) ); - - /* execute the action hook and pass the theme options to it */ - do_action( 'ot_before_theme_options_save', $new_options ); - - update_option( ot_options_id(), $new_options ); - - } - - /* update the option tree layouts array */ - update_option( ot_layouts_id(), $layouts ); - - $message = 'success'; - - } - - /* redirect accordingly */ - wp_redirect( esc_url_raw( add_query_arg( array( 'action' => 'import-layouts', 'message' => $message ), $_POST['_wp_http_referer'] ) ) ); - exit; - - } - - return false; - - } - + /** + * Import before the screen is displayed. + * + * @access public + * @since 2.0 + */ + function ot_import() { + + // Check and verify import settings nonce. + if ( isset( $_POST['import_settings_nonce'] ) && wp_verify_nonce( $_POST['import_settings_nonce'], 'import_settings_form' ) ) { // phpcs:ignore + + // Default message. + $message = 'failed'; + + $settings = isset( $_POST['import_settings'] ) ? ot_decode( sanitize_text_field( wp_unslash( $_POST['import_settings'] ) ) ) : array(); + + if ( is_array( $settings ) && ! empty( $settings ) ) { + + $settings_safe = ot_validate_settings( $settings ); + + // Save & show success message. + if ( is_array( $settings_safe ) ) { + update_option( ot_settings_id(), $settings_safe ); + $message = 'success'; + } + } + + // Redirect back to self. + wp_safe_redirect( + esc_url_raw( + add_query_arg( + array( + 'action' => 'import-settings', + 'message' => $message, + ), + wp_get_referer() + ) + ) + ); + exit; + } + + // Check and verify import theme options data nonce. + if ( isset( $_POST['import_data_nonce'] ) && wp_verify_nonce( $_POST['import_data_nonce'], 'import_data_form' ) ) { // phpcs:ignore + + // Default message. + $message = 'failed'; + $options = isset( $_POST['import_data'] ) ? ot_decode( sanitize_text_field( wp_unslash( $_POST['import_data'] ) ) ) : array(); + + if ( $options ) { + + $options_safe = array(); + + // Get settings array. + $settings = get_option( ot_settings_id() ); + + // Has options. + if ( is_array( $options ) ) { + + // Validate options. + if ( is_array( $settings ) ) { + foreach ( $settings['settings'] as $setting ) { + if ( isset( $options[ $setting['id'] ] ) ) { + $options_safe[ $setting['id'] ] = ot_validate_setting( wp_unslash( $options[ $setting['id'] ] ), $setting['type'], $setting['id'] ); + } + } + } + + // Execute the action hook and pass the theme options to it. + do_action( 'ot_before_theme_options_save', $options_safe ); + + // Update the option tree array. + update_option( ot_options_id(), $options_safe ); + + $message = 'success'; + } + } + + // Redirect back to self. + wp_safe_redirect( + esc_url_raw( + add_query_arg( + array( + 'action' => 'import-data', + 'message' => $message, + ), + wp_get_referer() + ) + ) + ); + exit; + } + + // Check and verify import layouts nonce. + if ( isset( $_POST['import_layouts_nonce'] ) && wp_verify_nonce( $_POST['import_layouts_nonce'], 'import_layouts_form' ) ) { // phpcs:ignore + + // Default message. + $message = 'failed'; + $layouts = isset( $_POST['import_layouts'] ) ? ot_decode( sanitize_text_field( wp_unslash( $_POST['import_layouts'] ) ) ) : array(); + + if ( $layouts ) { + + // Get settings array. + $settings = get_option( ot_settings_id() ); + + // Has layouts. + if ( is_array( $layouts ) && ! empty( $layouts ) && ! empty( $layouts['active_layout'] ) ) { + + $layouts_safe = array( + 'active_layout' => esc_attr( $layouts['active_layout'] ), + ); + + // Validate options. + if ( is_array( $settings ) ) { + + foreach ( $layouts as $key => $value ) { + + if ( 'active_layout' === $key ) { + continue; + } + + // Convert the options to an array. + $options = ot_decode( $value ); + + $options_safe = array(); + + foreach ( $settings['settings'] as $setting ) { + if ( isset( $options[ $setting['id'] ] ) ) { + $options_safe[ $setting['id'] ] = ot_validate_setting( wp_unslash( $options[ $setting['id'] ] ), $setting['type'], $setting['id'] ); + } + } + + // Store the sanitized values for later. + if ( $key === $layouts['active_layout'] ) { + $new_options_safe = $options_safe; + } + + $layouts_safe[ $key ] = ot_encode( $options_safe ); + } + } + + // Update the option tree array with sanitized values. + if ( isset( $new_options_safe ) ) { + + // Execute the action hook and pass the theme options to it. + do_action( 'ot_before_theme_options_save', $new_options_safe ); + + update_option( ot_options_id(), $new_options_safe ); + } + + // Update the option tree layouts array. + update_option( ot_layouts_id(), $layouts_safe ); + + $message = 'success'; + } + } + + // Redirect back to self. + wp_safe_redirect( + esc_url_raw( + add_query_arg( + array( + 'action' => 'import-layouts', + 'message' => $message, + ), + wp_get_referer() + ) + ) + ); + exit; + } + + return false; + } } -/** - * Export before the screen is displayed. - * - * @return void - * - * @access public - * @since 2.0.8 - */ if ( ! function_exists( 'ot_export' ) ) { - function ot_export() { - - /* check and verify export settings file nonce */ - if ( isset( $_POST['export_settings_file_nonce'] ) && wp_verify_nonce( $_POST['export_settings_file_nonce'], 'export_settings_file_form' ) ) { - - ot_export_php_settings_array(); - - } - - } - + /** + * Export before the screen is displayed. + * + * @return void + * + * @access public + * @since 2.0.8 + */ + function ot_export() { + + // Check and verify export settings file nonce. + if ( isset( $_POST['export_settings_file_nonce'] ) && wp_verify_nonce( $_POST['export_settings_file_nonce'], 'export_settings_file_form' ) ) { // phpcs:ignore + ot_export_php_settings_array(); + } + } } -/** - * Reusable XMl import helper function. - * - * @param string $file The path to the file. - * @return mixed False or an array of settings. - * - * @access public - * @since 2.0.8 - */ -if ( ! function_exists( 'ot_import_xml' ) ) { - - function ot_import_xml( $file ) { - - $get_data = wp_remote_get( $file ); - - if ( is_wp_error( $get_data ) ) - return false; - - $rawdata = isset( $get_data['body'] ) ? $get_data['body'] : false; - - if ( $rawdata ) { - - $section_count = 0; - $settings_count = 0; - - $section = ''; - - $settings = array(); - $xml = new SimpleXMLElement( $rawdata ); - - foreach ( $xml->row as $value ) { - - /* heading is a section now */ - if ( $value->item_type == 'heading' ) { - - /* add section to the sections array */ - $settings['sections'][$section_count]['id'] = (string) $value->item_id; - $settings['sections'][$section_count]['title'] = (string) $value->item_title; - - /* save the last section id to use in creating settings */ - $section = (string) $value->item_id; - - /* increment the section count */ - $section_count++; - - } else { - - /* add setting to the settings array */ - $settings['settings'][$settings_count]['id'] = (string) $value->item_id; - $settings['settings'][$settings_count]['label'] = (string) $value->item_title; - $settings['settings'][$settings_count]['desc'] = (string) $value->item_desc; - $settings['settings'][$settings_count]['section'] = $section; - $settings['settings'][$settings_count]['type'] = ot_map_old_option_types( (string) $value->item_type ); - $settings['settings'][$settings_count]['std'] = ''; - $settings['settings'][$settings_count]['class'] = ''; - - /* textarea rows */ - $rows = ''; - if ( in_array( $settings['settings'][$settings_count]['type'], array( 'css', 'javascript', 'textarea' ) ) ) { - if ( (int) $value->item_options > 0 ) { - $rows = (int) $value->item_options; - } else { - $rows = 15; - } - } - $settings['settings'][$settings_count]['rows'] = $rows; - - /* post type */ - $post_type = ''; - if ( in_array( $settings['settings'][$settings_count]['type'], array( 'custom-post-type-select', 'custom-post-type-checkbox' ) ) ) { - if ( '' != (string) $value->item_options ) { - $post_type = (string) $value->item_options; - } else { - $post_type = 'post'; - } - } - $settings['settings'][$settings_count]['post_type'] = $post_type; - - /* choices */ - $choices = array(); - if ( in_array( $settings['settings'][$settings_count]['type'], array( 'checkbox', 'radio', 'select' ) ) ) { - if ( '' != (string) $value->item_options ) { - $choices = ot_convert_string_to_array( (string) $value->item_options ); - } - } - $settings['settings'][$settings_count]['choices'] = $choices; - - $settings_count++; - } - - } - - /* make sure each setting has a section just incase */ - if ( isset( $settings['sections'] ) && isset( $settings['settings'] ) ) { - foreach( $settings['settings'] as $k => $setting ) { - if ( '' == $setting['section'] ) { - $settings['settings'][$k]['section'] = $settings['sections'][0]['id']; - } - } - } - - return $settings; - - } - - return false; - } - -} - -/** - * Export the Theme Mode theme-options.php - * - * @return attachment - * - * @access public - * @since 2.0.8 - */ if ( ! function_exists( 'ot_export_php_settings_array' ) ) { - function ot_export_php_settings_array() { - - $content = ''; - $build_settings = ''; - $contextual_help = ''; - $sections = ''; - $settings = ''; - $option_tree_settings = get_option( ot_settings_id(), array() ); - - // Domain string helper - function ot_I18n_string( $string ) { - if ( ! empty( $string ) && isset( $_POST['domain'] ) && ! empty( $_POST['domain'] ) ) { - $domain = str_replace( ' ', '-', trim( $_POST['domain'] ) ); - return "__( '$string', '$domain' )"; - } - return "'$string'"; - } - - header( "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0"); - header( "Pragma: no-cache "); - header( "Content-Description: File Transfer" ); - header( 'Content-Disposition: attachment; filename="theme-options.php"'); - header( "Content-Type: application/octet-stream"); - header( "Content-Transfer-Encoding: binary" ); - - /* build contextual help content */ - if ( isset( $option_tree_settings['contextual_help']['content'] ) ) { - $help = ''; - foreach( $option_tree_settings['contextual_help']['content'] as $value ) { - $_id = isset( $value['id'] ) ? $value['id'] : ''; - $_title = ot_I18n_string( isset( $value['title'] ) ? str_replace( "'", "\'", $value['title'] ) : '' ); - $_content = ot_I18n_string( isset( $value['content'] ) ? html_entity_decode( str_replace( "'", "\'", $value['content'] ) ) : '' ); - $help.= " - array( - 'id' => '$_id', - 'title' => $_title, - 'content' => $_content - ),"; - } - $help = substr_replace( $help, '' , -1 ); - $contextual_help = " - 'content' => array( $help - ),"; - } - - /* build contextual help sidebar */ - if ( isset( $option_tree_settings['contextual_help']['sidebar'] ) ) { - $contextual_help.= " - 'sidebar' => " . ot_I18n_string( html_entity_decode( str_replace( "'", "\'", $option_tree_settings['contextual_help']['sidebar'] ) ) ); - } - - /* check that $contexual_help has a value and add to $build_settings */ - if ( '' != $contextual_help ) { - $build_settings.= " - 'contextual_help' => array( $contextual_help - ),"; - } - - /* build sections */ - if ( isset( $option_tree_settings['sections'] ) ) { - foreach( $option_tree_settings['sections'] as $value ) { - $_id = isset( $value['id'] ) ? $value['id'] : ''; - $_title = ot_I18n_string( isset( $value['title'] ) ? str_replace( "'", "\'", $value['title'] ) : '' ); - $sections.= " - array( - 'id' => '$_id', - 'title' => $_title - ),"; - } - $sections = substr_replace( $sections, '' , -1 ); - } - - /* check that $sections has a value and add to $build_settings */ - if ( '' != $sections ) { - $build_settings.= " - 'sections' => array( $sections - )"; - } - - /* build settings */ - if ( isset( $option_tree_settings['settings'] ) ) { - foreach( $option_tree_settings['settings'] as $value ) { - $_id = isset( $value['id'] ) ? $value['id'] : ''; - $_label = ot_I18n_string( isset( $value['label'] ) ? str_replace( "'", "\'", $value['label'] ) : '' ); - $_desc = ot_I18n_string( isset( $value['desc'] ) ? str_replace( "'", "\'", $value['desc'] ) : '' ); - $_std = isset( $value['std'] ) ? str_replace( "'", "\'", $value['std'] ) : ''; - $_type = isset( $value['type'] ) ? $value['type'] : ''; - $_section = isset( $value['section'] ) ? $value['section'] : ''; - $_rows = isset( $value['rows'] ) ? $value['rows'] : ''; - $_post_type = isset( $value['post_type'] ) ? $value['post_type'] : ''; - $_taxonomy = isset( $value['taxonomy'] ) ? $value['taxonomy'] : ''; - $_min_max_step = isset( $value['min_max_step'] ) ? $value['min_max_step'] : ''; - $_class = isset( $value['class'] ) ? $value['class'] : ''; - $_condition = isset( $value['condition'] ) ? $value['condition'] : ''; - $_operator = isset( $value['operator'] ) ? $value['operator'] : ''; - - $choices = ''; - if ( isset( $value['choices'] ) && ! empty( $value['choices'] ) ) { - foreach( $value['choices'] as $choice ) { - $_choice_value = isset( $choice['value'] ) ? str_replace( "'", "\'", $choice['value'] ) : ''; - $_choice_label = ot_I18n_string( isset( $choice['label'] ) ? str_replace( "'", "\'", $choice['label'] ) : '' ); - $_choice_src = isset( $choice['src'] ) ? str_replace( "'", "\'", $choice['src'] ) : ''; - $choices.= " - array( - 'value' => '$_choice_value', - 'label' => $_choice_label, - 'src' => '$_choice_src' - ),"; - } - $choices = substr_replace( $choices, '' , -1 ); - $choices = ", - 'choices' => array( $choices - )"; - } - - $std = "'$_std'"; - if ( is_array( $_std ) ) { - $std_array = array(); - foreach( $_std as $_sk => $_sv ) { - $std_array[] = "'$_sk' => '$_sv'"; - } - $std = 'array( + /** + * Export the Theme Mode theme-options.php + * + * @access public + * @since 2.0.8 + */ + function ot_export_php_settings_array() { + + $content = ''; + $build_settings = ''; + $contextual_help = ''; + $sections = ''; + $settings = ''; + $option_tree_settings = get_option( ot_settings_id(), array() ); + + /** + * Domain string helper. + * + * @param string $string A string. + * @return string + */ + function ot_i18n_string( $string ) { + if ( ! empty( $string ) && isset( $_POST['domain'] ) && ! empty( $_POST['domain'] ) ) { // phpcs:ignore + $domain = str_replace( ' ', '-', trim( sanitize_text_field( wp_unslash( $_POST['domain'] ) ) ) ); // phpcs:ignore + return "esc_html__( '$string', '$domain' )"; + } + return "'$string'"; + } + + header( 'Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0' ); + header( 'Pragma: no-cache ' ); + header( 'Content-Description: File Transfer' ); + header( 'Content-Disposition: attachment; filename="theme-options.php"' ); + header( 'Content-Type: application/octet-stream' ); + header( 'Content-Transfer-Encoding: binary' ); + + // Build contextual help content. + if ( isset( $option_tree_settings['contextual_help']['content'] ) ) { + $help = ''; + foreach ( $option_tree_settings['contextual_help']['content'] as $value ) { + $_id = isset( $value['id'] ) ? $value['id'] : ''; + $_title = ot_i18n_string( isset( $value['title'] ) ? str_replace( "'", "\'", $value['title'] ) : '' ); + $_content = ot_i18n_string( isset( $value['content'] ) ? html_entity_decode( str_replace( "'", "\'", $value['content'] ) ) : '' ); + $help .= " + array( + 'id' => '$_id', + 'title' => $_title, + 'content' => $_content, + ),"; + } + $contextual_help = " + 'content' => array($help + ),"; + } + + // Build contextual help sidebar. + if ( isset( $option_tree_settings['contextual_help']['sidebar'] ) ) { + $_sidebar = ot_i18n_string( html_entity_decode( str_replace( "'", "\'", $option_tree_settings['contextual_help']['sidebar'] ) ) ); + $contextual_help .= " + 'sidebar' => $_sidebar,"; + } + + // Check that $contexual_help has a value and add to $build_settings. + if ( '' !== $contextual_help ) { + $build_settings .= " + 'contextual_help' => array($contextual_help + ),"; + } + + // Build sections. + if ( isset( $option_tree_settings['sections'] ) ) { + foreach ( $option_tree_settings['sections'] as $value ) { + $_id = isset( $value['id'] ) ? $value['id'] : ''; + $_title = ot_i18n_string( isset( $value['title'] ) ? str_replace( "'", "\'", $value['title'] ) : '' ); + $sections .= " + array( + 'id' => '$_id', + 'title' => $_title, + ),"; + } + } + + // Check that $sections has a value and add to $build_settings. + if ( '' !== $sections ) { + $build_settings .= " + 'sections' => array($sections + )"; + } + + /* build settings */ + if ( isset( $option_tree_settings['settings'] ) ) { + foreach ( $option_tree_settings['settings'] as $value ) { + $_id = isset( $value['id'] ) ? $value['id'] : ''; + $_label = ot_i18n_string( isset( $value['label'] ) ? str_replace( "'", "\'", $value['label'] ) : '' ); + $_desc = ot_i18n_string( isset( $value['desc'] ) ? str_replace( "'", "\'", $value['desc'] ) : '' ); + $_std = isset( $value['std'] ) ? str_replace( "'", "\'", $value['std'] ) : ''; + $_type = isset( $value['type'] ) ? $value['type'] : ''; + $_section = isset( $value['section'] ) ? $value['section'] : ''; + $_rows = isset( $value['rows'] ) ? $value['rows'] : ''; + $_post_type = isset( $value['post_type'] ) ? $value['post_type'] : ''; + $_taxonomy = isset( $value['taxonomy'] ) ? $value['taxonomy'] : ''; + $_min_max_step = isset( $value['min_max_step'] ) ? $value['min_max_step'] : ''; + $_class = isset( $value['class'] ) ? $value['class'] : ''; + $_condition = isset( $value['condition'] ) ? $value['condition'] : ''; + $_operator = isset( $value['operator'] ) ? $value['operator'] : ''; + + $choices = ''; + if ( isset( $value['choices'] ) && ! empty( $value['choices'] ) ) { + foreach ( $value['choices'] as $choice ) { + $_choice_value = isset( $choice['value'] ) ? str_replace( "'", "\'", $choice['value'] ) : ''; + $_choice_label = ot_i18n_string( isset( $choice['label'] ) ? str_replace( "'", "\'", $choice['label'] ) : '' ); + $_choice_src = isset( $choice['src'] ) ? str_replace( "'", "\'", $choice['src'] ) : ''; + $choices .= " + array( + 'value' => '$_choice_value', + 'label' => $_choice_label, + 'src' => '$_choice_src', + ),"; + } + $choices = " + 'choices' => array($choices + ),"; + } + + $std = "'$_std'"; + if ( is_array( $_std ) ) { + $std_array = array(); + foreach ( $_std as $_sk => $_sv ) { + $std_array[] = "'$_sk' => '$_sv',"; + } + $std = 'array( ' . implode( ",\n", $std_array ) . ' - )'; - } - - $setting_settings = ''; - if ( isset( $value['settings'] ) && ! empty( $value['settings'] ) ) { - foreach( $value['settings'] as $setting ) { - $_setting_id = isset( $setting['id'] ) ? $setting['id'] : ''; - $_setting_label = ot_I18n_string( isset( $setting['label'] ) ? str_replace( "'", "\'", $setting['label'] ) : '' ); - $_setting_desc = ot_I18n_string( isset( $setting['desc'] ) ? str_replace( "'", "\'", $setting['desc'] ) : '' ); - $_setting_std = isset( $setting['std'] ) ? $setting['std'] : ''; - $_setting_type = isset( $setting['type'] ) ? $setting['type'] : ''; - $_setting_rows = isset( $setting['rows'] ) ? $setting['rows'] : ''; - $_setting_post_type = isset( $setting['post_type'] ) ? $setting['post_type'] : ''; - $_setting_taxonomy = isset( $setting['taxonomy'] ) ? $setting['taxonomy'] : ''; - $_setting_min_max_step = isset( $setting['min_max_step'] ) ? $setting['min_max_step'] : ''; - $_setting_class = isset( $setting['class'] ) ? $setting['class'] : ''; - $_setting_condition = isset( $setting['condition'] ) ? $setting['condition'] : ''; - $_setting_operator = isset( $setting['operator'] ) ? $setting['operator'] : ''; - - $setting_choices = ''; - if ( isset( $setting['choices'] ) && ! empty( $setting['choices'] ) ) { - foreach( $setting['choices'] as $setting_choice ) { - $_setting_choice_value = isset( $setting_choice['value'] ) ? $setting_choice['value'] : ''; - $_setting_choice_label = ot_I18n_string( isset( $setting_choice['label'] ) ? str_replace( "'", "\'", $setting_choice['label'] ) : '' ); - $_setting_choice_src = isset( $setting_choice['src'] ) ? str_replace( "'", "\'", $setting_choice['src'] ) : ''; - $setting_choices.= " - array( - 'value' => '$_setting_choice_value', - 'label' => $_setting_choice_label, - 'src' => '$_setting_choice_src' - ),"; - } - $setting_choices = substr_replace( $setting_choices, '' , -1 ); - $setting_choices = ", - 'choices' => array( $setting_choices - )"; - } - - $setting_std = "'$_setting_std'"; - if ( is_array( $_setting_std ) ) { - $setting_std_array = array(); - foreach( $_setting_std as $_ssk => $_ssv ) { - $setting_std_array[] = "'$_ssk' => '$_ssv'"; - } - $setting_std = 'array( + )'; + } + + $setting_settings = ''; + if ( isset( $value['settings'] ) && ! empty( $value['settings'] ) ) { + foreach ( $value['settings'] as $setting ) { + $_setting_id = isset( $setting['id'] ) ? $setting['id'] : ''; + $_setting_label = ot_i18n_string( isset( $setting['label'] ) ? str_replace( "'", "\'", $setting['label'] ) : '' ); + $_setting_desc = ot_i18n_string( isset( $setting['desc'] ) ? str_replace( "'", "\'", $setting['desc'] ) : '' ); + $_setting_std = isset( $setting['std'] ) ? $setting['std'] : ''; + $_setting_type = isset( $setting['type'] ) ? $setting['type'] : ''; + $_setting_rows = isset( $setting['rows'] ) ? $setting['rows'] : ''; + $_setting_post_type = isset( $setting['post_type'] ) ? $setting['post_type'] : ''; + $_setting_taxonomy = isset( $setting['taxonomy'] ) ? $setting['taxonomy'] : ''; + $_setting_min_max_step = isset( $setting['min_max_step'] ) ? $setting['min_max_step'] : ''; + $_setting_class = isset( $setting['class'] ) ? $setting['class'] : ''; + $_setting_condition = isset( $setting['condition'] ) ? $setting['condition'] : ''; + $_setting_operator = isset( $setting['operator'] ) ? $setting['operator'] : ''; + + $setting_choices = ''; + if ( isset( $setting['choices'] ) && ! empty( $setting['choices'] ) ) { + foreach ( $setting['choices'] as $setting_choice ) { + $_setting_choice_value = isset( $setting_choice['value'] ) ? $setting_choice['value'] : ''; + $_setting_choice_label = ot_i18n_string( isset( $setting_choice['label'] ) ? str_replace( "'", "\'", $setting_choice['label'] ) : '' ); + $_setting_choice_src = isset( $setting_choice['src'] ) ? str_replace( "'", "\'", $setting_choice['src'] ) : ''; + $setting_choices .= " + array( + 'value' => '$_setting_choice_value', + 'label' => $_setting_choice_label, + 'src' => '$_setting_choice_src', + ),"; + } + $setting_choices = " + 'choices' => array($setting_choices + ),"; + } + + $setting_std = "'$_setting_std'"; + if ( is_array( $_setting_std ) ) { + $setting_std_array = array(); + foreach ( $_setting_std as $_ssk => $_ssv ) { + $setting_std_array[] = "'$_ssk' => '$_ssv'"; + } + $setting_std = 'array( ' . implode( ",\n", $setting_std_array ) . ' - )'; - } - - $setting_settings.= " - array( - 'id' => '$_setting_id', - 'label' => $_setting_label, - 'desc' => $_setting_desc, - 'std' => $setting_std, - 'type' => '$_setting_type', - 'rows' => '$_setting_rows', - 'post_type' => '$_setting_post_type', - 'taxonomy' => '$_setting_taxonomy', - 'min_max_step'=> '$_setting_min_max_step', - 'class' => '$_setting_class', - 'condition' => '$_setting_condition', - 'operator' => '$_setting_operator'$setting_choices - ),"; - } - $setting_settings = substr_replace( $setting_settings, '' , -1 ); - $setting_settings = ", - 'settings' => array( $setting_settings - )"; - } - - $settings.= " - array( - 'id' => '$_id', - 'label' => $_label, - 'desc' => $_desc, - 'std' => $std, - 'type' => '$_type', - 'section' => '$_section', - 'rows' => '$_rows', - 'post_type' => '$_post_type', - 'taxonomy' => '$_taxonomy', - 'min_max_step'=> '$_min_max_step', - 'class' => '$_class', - 'condition' => '$_condition', - 'operator' => '$_operator'$choices$setting_settings - ),"; - } - $settings = substr_replace( $settings, '' , -1 ); - } - - /* check that $sections has a value and add to $build_settings */ - if ( '' != $settings ) { - $build_settings.= ", - 'settings' => array( $settings - )"; - } - - $content.= " '$_setting_id', + 'label' => $_setting_label, + 'desc' => $_setting_desc, + 'std' => $setting_std, + 'type' => '$_setting_type', + 'rows' => '$_setting_rows', + 'post_type' => '$_setting_post_type', + 'taxonomy' => '$_setting_taxonomy', + 'min_max_step' => '$_setting_min_max_step', + 'class' => '$_setting_class', + 'condition' => '$_setting_condition', + 'operator' => '$_setting_operator',$setting_choices + ),"; + } + $setting_settings = " + 'settings' => array( $setting_settings + ),"; + } + $settings .= " + array( + 'id' => '$_id', + 'label' => $_label, + 'desc' => $_desc, + 'std' => $std, + 'type' => '$_type', + 'section' => '$_section', + 'rows' => '$_rows', + 'post_type' => '$_post_type', + 'taxonomy' => '$_taxonomy', + 'min_max_step' => '$_min_max_step', + 'class' => '$_class', + 'condition' => '$_condition', + 'operator' => '$_operator',$choices$setting_settings + ),"; + } + } + + // Check that $sections has a value and add to $build_settings. + if ( '' !== $settings ) { + $build_settings .= ", + 'settings' => array($settings + )"; + } + + $content .= " $section ) { - - /* remove from array if missing values */ - if ( ( ! isset( $section['title'] ) && ! isset( $section['id'] ) ) || ( '' == $section['title'] && '' == $section['id'] ) ) { - - unset( $settings['sections'][$k] ); - - } else { - - /* validate label */ - if ( '' != $section['title'] ) { - - $settings['sections'][$k]['title'] = wp_kses_post( $section['title'] ); - - } - - /* missing title set to unfiltered ID */ - if ( ! isset( $section['title'] ) || '' == $section['title'] ) { - - $settings['sections'][$k]['title'] = wp_kses_post( $section['id'] ); - - /* missing ID set to title */ - } else if ( ! isset( $section['id'] ) || '' == $section['id'] ) { - - $section['id'] = wp_kses_post( $section['title'] ); - - } - - /* sanitize ID once everything has been checked first */ - $settings['sections'][$k]['id'] = ot_sanitize_option_id( wp_kses_post( $section['id'] ) ); - - } - - } - - $settings['sections'] = ot_stripslashes( $settings['sections'] ); - - } - - /* validate settings by looping over array as many times as it takes */ - if ( isset( $settings['settings'] ) ) { - - $settings['settings'] = ot_validate_settings_array( $settings['settings'] ); - - } - - /* validate contextual_help */ - if ( isset( $settings['contextual_help']['content'] ) ) { - - /* fix numeric keys since drag & drop will change them */ - $settings['contextual_help']['content'] = array_values( $settings['contextual_help']['content'] ); - - /* loop through content */ - foreach( $settings['contextual_help']['content'] as $k => $content ) { - - /* remove from array if missing values */ - if ( ( ! isset( $content['title'] ) && ! isset( $content['id'] ) ) || ( '' == $content['title'] && '' == $content['id'] ) ) { - - unset( $settings['contextual_help']['content'][$k] ); - - } else { - - /* validate label */ - if ( '' != $content['title'] ) { - - $settings['contextual_help']['content'][$k]['title'] = wp_kses_post( $content['title'] ); - - } - - /* missing title set to unfiltered ID */ - if ( ! isset( $content['title'] ) || '' == $content['title'] ) { - - $settings['contextual_help']['content'][$k]['title'] = wp_kses_post( $content['id'] ); - - /* missing ID set to title */ - } else if ( ! isset( $content['id'] ) || '' == $content['id'] ) { - - $content['id'] = wp_kses_post( $content['title'] ); - - } - - /* sanitize ID once everything has been checked first */ - $settings['contextual_help']['content'][$k]['id'] = ot_sanitize_option_id( wp_kses_post( $content['id'] ) ); - - } - - /* validate textarea description */ - if ( isset( $content['content'] ) ) { - - $settings['contextual_help']['content'][$k]['content'] = wp_kses_post( $content['content'] ); - - } - - } - - } - - /* validate contextual_help sidebar */ - if ( isset( $settings['contextual_help']['sidebar'] ) ) { - - $settings['contextual_help']['sidebar'] = wp_kses_post( $settings['contextual_help']['sidebar'] ); - - } - - $settings['contextual_help'] = ot_stripslashes( $settings['contextual_help'] ); - - /* default message */ - $message = 'failed'; - - /* is array: save & show success message */ - if ( is_array( $settings ) ) { - - /* WPML unregister ID's that have been removed */ - if ( function_exists( 'icl_unregister_string' ) ) { - - $current = get_option( ot_settings_id() ); - $options = get_option( ot_options_id() ); - - if ( isset( $current['settings'] ) ) { - - /* Empty ID array */ - $new_ids = array(); - - /* Build the WPML IDs array */ - foreach( $settings['settings'] as $setting ) { - - if ( $setting['id'] ) { - - $new_ids[] = $setting['id']; - - } - - } - - /* Remove missing IDs from WPML */ - foreach( $current['settings'] as $current_setting ) { - - if ( ! in_array( $current_setting['id'], $new_ids ) ) { - - if ( ! empty( $options[$current_setting['id']] ) && in_array( $current_setting['type'], array( 'list-item', 'slider' ) ) ) { - - foreach( $options[$current_setting['id']] as $key => $value ) { - - foreach( $value as $ckey => $cvalue ) { - - ot_wpml_unregister_string( $current_setting['id'] . '_' . $ckey . '_' . $key ); - - } - - } - - } else if ( ! empty( $options[$current_setting['id']] ) && $current_setting['type'] == 'social-icons' ) { - - foreach( $options[$current_setting['id']] as $key => $value ) { - - foreach( $value as $ckey => $cvalue ) { - - ot_wpml_unregister_string( $current_setting['id'] . '_' . $ckey . '_' . $key ); - - } - - } - - } else { - - ot_wpml_unregister_string( $current_setting['id'] ); - - } - - } - - } - - } - - } - - update_option( ot_settings_id(), $settings ); - $message = 'success'; - - } - - /* redirect */ - wp_redirect( esc_url_raw( add_query_arg( array( 'action' => 'save-settings', 'message' => $message ), $_POST['_wp_http_referer'] ) ) ); - exit; - - } - - return false; - - } - + /** + * Save settings array before the screen is displayed. + * + * @return bool Redirects on save, false on failure. + * + * @access public + * @since 2.0 + */ + function ot_save_settings() { + + // Check and verify import settings nonce. + if ( isset( $_POST['option_tree_settings_nonce'] ) && wp_verify_nonce( $_POST['option_tree_settings_nonce'], 'option_tree_settings_form' ) ) { // phpcs:ignore + + // Settings value. + $settings = isset( $_POST[ ot_settings_id() ] ) ? wp_unslash( $_POST[ ot_settings_id() ] ) : array(); // phpcs:ignore + + $settings_safe = ot_validate_settings( $settings ); + + // Default message. + $message = 'failed'; + + // Save & show success message. + if ( ! empty( $settings_safe ) ) { + ot_wpml_unregister( $settings_safe ); + + update_option( ot_settings_id(), $settings_safe ); + $message = 'success'; + } + + // Redirect. + wp_safe_redirect( + esc_url_raw( + add_query_arg( + array( + 'action' => 'save-settings', + 'message' => $message, + ), + wp_get_referer() + ) + ) + ); + exit; + } + + return false; + } +} + +if ( ! function_exists( 'ot_wpml_unregister' ) ) { + + /** + * Unregister WPML strings based on settings changing. + * + * @param array $settings The array of settings. + * + * @access public + * @since 2.7.0 + */ + function ot_wpml_unregister( $settings = array() ) { + + // WPML unregister ID's that have been removed. + if ( function_exists( 'icl_unregister_string' ) ) { + + $current = get_option( ot_settings_id() ); + $options = get_option( ot_options_id() ); + + if ( isset( $current['settings'] ) ) { + + // Empty ID array. + $new_ids = array(); + + // Build the WPML IDs array. + foreach ( $settings['settings'] as $setting ) { + if ( $setting['id'] ) { + $new_ids[] = $setting['id']; + } + } + + // Remove missing IDs from WPML. + foreach ( $current['settings'] as $current_setting ) { + if ( ! in_array( $current_setting['id'], $new_ids, true ) ) { + if ( ! empty( $options[ $current_setting['id'] ] ) && in_array( $current_setting['type'], array( 'list-item', 'slider' ), true ) ) { + foreach ( $options[ $current_setting['id'] ] as $key => $value ) { + foreach ( $value as $ckey => $cvalue ) { + ot_wpml_unregister_string( $current_setting['id'] . '_' . $ckey . '_' . $key ); + } + } + } elseif ( ! empty( $options[ $current_setting['id'] ] ) && 'social-icons' === $current_setting['type'] ) { + foreach ( $options[ $current_setting['id'] ] as $key => $value ) { + foreach ( $value as $ckey => $cvalue ) { + ot_wpml_unregister_string( $current_setting['id'] . '_' . $ckey . '_' . $key ); + } + } + } else { + ot_wpml_unregister_string( $current_setting['id'] ); + } + } + } + } + } + } } -/** - * Validate the settings array before save. - * - * This function will loop over the settings array as many - * times as it takes to validate every sub setting. - * - * @param array $settings The array of settings. - * @return array - * - * @access public - * @since 2.0 - */ +if ( ! function_exists( 'ot_validate_settings' ) ) { + + /** + * Helper function to validate all settings. + * + * This includes the `sections`, `settings`, and `contextual_help` arrays. + * + * @param array $settings The array of settings. + * + * @return array + * + * @access public + * @since 2.7.0 + */ + function ot_validate_settings( $settings = array() ) { + + // Store the validated settings. + $settings_safe = array(); + + // Validate sections. + if ( isset( $settings['sections'] ) ) { + + // Fix numeric keys since drag & drop will change them. + $settings['sections'] = array_values( $settings['sections'] ); + + // Loop through sections. + foreach ( $settings['sections'] as $k => $section ) { + + // Skip if missing values. + if ( ( ! isset( $section['title'] ) && ! isset( $section['id'] ) ) || ( '' === $section['title'] && '' === $section['id'] ) ) { + continue; + } + + // Validate label. + if ( '' !== $section['title'] ) { + $settings_safe['sections'][ $k ]['title'] = wp_kses_post( $section['title'] ); + } + + // Missing title set to unfiltered ID. + if ( ! isset( $section['title'] ) || '' === $section['title'] ) { + + $settings_safe['sections'][ $k ]['title'] = wp_kses_post( $section['id'] ); + + // Missing ID set to title. + } elseif ( ! isset( $section['id'] ) || '' === $section['id'] ) { + + $settings_safe['id'] = wp_kses_post( $section['title'] ); + } + + // Sanitize ID once everything has been checked first. + $settings_safe['sections'][ $k ]['id'] = ot_sanitize_option_id( wp_kses_post( $section['id'] ) ); + } + } + + // Validate settings by looping over array as many times as it takes. + if ( isset( $settings['settings'] ) ) { + $settings_safe['settings'] = ot_validate_settings_array( $settings['settings'] ); + } + + // Validate contextual_help. + if ( isset( $settings['contextual_help']['content'] ) ) { + + // Fix numeric keys since drag & drop will change them. + $settings['contextual_help']['content'] = array_values( $settings['contextual_help']['content'] ); + + // Loop through content. + foreach ( $settings['contextual_help']['content'] as $k => $content ) { + + // Skip if missing values. + if ( ( ! isset( $content['title'] ) && ! isset( $content['id'] ) ) || ( '' === $content['title'] && '' === $content['id'] ) ) { + continue; + } + + // Validate label. + if ( '' !== $content['title'] ) { + $settings_safe['contextual_help']['content'][ $k ]['title'] = wp_kses_post( $content['title'] ); + } + + // Missing title set to unfiltered ID. + if ( ! isset( $content['title'] ) || '' === $content['title'] ) { + + $settings_safe['contextual_help']['content'][ $k ]['title'] = wp_kses_post( $content['id'] ); + + // Missing ID set to title. + } elseif ( ! isset( $content['id'] ) || '' === $content['id'] ) { + + $content['id'] = wp_kses_post( $content['title'] ); + } + + // Sanitize ID once everything has been checked first. + $settings_safe['contextual_help']['content'][ $k ]['id'] = ot_sanitize_option_id( wp_kses_post( $content['id'] ) ); + + // Validate textarea description. + if ( isset( $content['content'] ) ) { + $settings_safe['contextual_help']['content'][ $k ]['content'] = wp_kses_post( $content['content'] ); + } + } + } + + // Validate contextual_help sidebar. + if ( isset( $settings['contextual_help']['sidebar'] ) ) { + $settings_safe['contextual_help']['sidebar'] = wp_kses_post( $settings['contextual_help']['sidebar'] ); + } + + return $settings_safe; + } +} + if ( ! function_exists( 'ot_validate_settings_array' ) ) { - function ot_validate_settings_array( $settings = array() ) { - - /* validate settings */ - if ( count( $settings ) > 0 ) { - - /* fix numeric keys since drag & drop will change them */ - $settings = array_values( $settings ); - - /* loop through settings */ - foreach( $settings as $k => $setting ) { - - - /* remove from array if missing values */ - if ( ( ! isset( $setting['label'] ) && ! isset( $setting['id'] ) ) || ( '' == $setting['label'] && '' == $setting['id'] ) ) { - - unset( $settings[$k] ); - - } else { - - /* validate label */ - if ( '' != $setting['label'] ) { - - $settings[$k]['label'] = wp_kses_post( $setting['label'] ); - - } - - /* missing label set to unfiltered ID */ - if ( ! isset( $setting['label'] ) || '' == $setting['label'] ) { - - $settings[$k]['label'] = $setting['id']; - - /* missing ID set to label */ - } else if ( ! isset( $setting['id'] ) || '' == $setting['id'] ) { - - $setting['id'] = wp_kses_post( $setting['label'] ); - - } - - /* sanitize ID once everything has been checked first */ - $settings[$k]['id'] = ot_sanitize_option_id( wp_kses_post( $setting['id'] ) ); - - } - - /* validate description */ - if ( '' != $setting['desc'] ) { - - $settings[$k]['desc'] = wp_kses_post( $setting['desc'] ); - - } - - /* validate choices */ - if ( isset( $setting['choices'] ) ) { - - /* loop through choices */ - foreach( $setting['choices'] as $ck => $choice ) { - - /* remove from array if missing values */ - if ( ( ! isset( $choice['label'] ) && ! isset( $choice['value'] ) ) || ( '' == $choice['label'] && '' == $choice['value'] ) ) { - - unset( $setting['choices'][$ck] ); - - } else { - - /* missing label set to unfiltered ID */ - if ( ! isset( $choice['label'] ) || '' == $choice['label'] ) { - - $setting['choices'][$ck]['label'] = wp_kses_post( $choice['value'] ); - - /* missing value set to label */ - } else if ( ! isset( $choice['value'] ) || '' == $choice['value'] ) { - - $setting['choices'][$ck]['value'] = ot_sanitize_option_id( wp_kses_post( $choice['label'] ) ); - - } - - } - - } - - /* update keys and push new array values */ - $settings[$k]['choices'] = array_values( $setting['choices'] ); - - } - - /* validate sub settings */ - if ( isset( $setting['settings'] ) ) { - - $settings[$k]['settings'] = ot_validate_settings_array( $setting['settings'] ); - - } - - } - - } - - /* return array but strip those damn slashes out first!!! */ - return ot_stripslashes( $settings ); - - } - + /** + * Validate a settings array before save. + * + * This function will loop over a settings array as many + * times as it takes to validate every sub setting. + * + * @param array $settings The array of settings. + * @return array + * + * @access public + * @since 2.0 + * @updated 2.7.0 + */ + function ot_validate_settings_array( $settings = array() ) { + + // Field types mapped to their sanitize function. + $field_types = array( + 'label' => 'wp_kses_post', + 'id' => 'ot_sanitize_option_id', + 'type' => 'sanitize_text_field', + 'desc' => 'wp_kses_post', + 'settings' => 'ot_validate_settings_array', + 'choices' => array( + 'label' => 'wp_kses_post', + 'value' => 'sanitize_text_field', + 'src' => 'sanitize_text_field', + ), + 'std' => 'sanitize_text_field', + 'rows' => 'absint', + 'post_type' => 'sanitize_text_field', + 'taxonomy' => 'sanitize_text_field', + 'min_max_step' => 'sanitize_text_field', + 'class' => 'sanitize_text_field', + 'condition' => 'sanitize_text_field', + 'operator' => 'sanitize_text_field', + 'section' => 'sanitize_text_field', + ); + + // Store the validated settings. + $settings_safe = array(); + + // Validate settings. + if ( 0 < count( $settings ) ) { + + // Fix numeric keys since drag & drop will change them. + $settings = array_values( $settings ); + + // Loop through settings. + foreach ( $settings as $sk => $setting ) { + foreach ( $setting as $fk => $field ) { + if ( isset( $field_types[ $fk ] ) ) { + if ( 'choices' === $fk ) { + foreach ( $field as $ck => $choice ) { + foreach ( $choice as $vk => $value ) { + $settings_safe[ $sk ][ $fk ][ $ck ][ $vk ] = call_user_func( $field_types[ $fk ][ $vk ], $value ); + } + } + } elseif ( 'std' === $fk && is_array( $field ) ) { + $callback = $field_types[ $fk ]; + $array_map = function( $item ) use ( $array_map, $callback ) { + return is_array( $item ) ? array_map( $array_map, $item ) : call_user_func( $callback, $item ); + }; + + $settings_safe[ $sk ][ $fk ] = array_map( $array_map, $field ); + } else { + $sanitized = call_user_func( $field_types[ $fk ], $field ); + if ( 'rows' === $fk && 0 === $sanitized ) { + $sanitized = ''; + } + $settings_safe[ $sk ][ $fk ] = $sanitized; + } + } + } + } + } + + return $settings_safe; + } } -/** - * Save layouts array before the screen is displayed. - * - * @return void - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_modify_layouts' ) ) { - function ot_modify_layouts() { - - /* check and verify modify layouts nonce */ - if ( isset( $_POST['option_tree_modify_layouts_nonce'] ) && wp_verify_nonce( $_POST['option_tree_modify_layouts_nonce'], 'option_tree_modify_layouts_form' ) ) { - - /* previous layouts value */ - $option_tree_layouts = get_option( ot_layouts_id() ); - - /* new layouts value */ - $layouts = isset( $_POST[ot_layouts_id()] ) ? $_POST[ot_layouts_id()] : ''; - - /* rebuild layout array */ - $rebuild = array(); - - /* validate layouts */ - if ( is_array( $layouts ) && ! empty( $layouts ) ) { - - /* setup active layout */ - if ( isset( $layouts['active_layout'] ) && ! empty( $layouts['active_layout'] ) ) { - $rebuild['active_layout'] = $layouts['active_layout']; - } - - /* add new and overwrite active layout */ - if ( isset( $layouts['_add_new_layout_'] ) && ! empty( $layouts['_add_new_layout_'] ) ) { - $rebuild['active_layout'] = ot_sanitize_layout_id( $layouts['_add_new_layout_'] ); - $rebuild[$rebuild['active_layout']] = ot_encode( serialize( get_option( ot_options_id() ) ) ); - } - - $first_layout = ''; - - /* loop through layouts */ - foreach( $layouts as $key => $layout ) { - - /* skip over active layout key */ - if ( $key == 'active_layout' ) - continue; - - /* check if the key exists then set value */ - if ( isset( $option_tree_layouts[$key] ) && ! empty( $option_tree_layouts[$key] ) ) { - $rebuild[$key] = $option_tree_layouts[$key]; - if ( '' == $first_layout ) { - $first_layout = $key; - } - } - - } - - if ( isset( $rebuild['active_layout'] ) && ! isset( $rebuild[$rebuild['active_layout']] ) && ! empty( $first_layout ) ) { - $rebuild['active_layout'] = $first_layout; - } - - } - - /* default message */ - $message = 'failed'; - - /* is array: save & show success message */ - if ( count( $rebuild ) > 1 ) { - - /* rebuild the theme options */ - $rebuild_option_tree = unserialize( ot_decode( $rebuild[$rebuild['active_layout']] ) ); - if ( is_array( $rebuild_option_tree ) ) { - - /* execute the action hook and pass the theme options to it */ - do_action( 'ot_before_theme_options_save', $rebuild_option_tree ); - - update_option( ot_options_id(), $rebuild_option_tree ); - - } - - /* rebuild the layouts */ - update_option( ot_layouts_id(), $rebuild ); - - /* change message */ - $message = 'success'; - - } else if ( count( $rebuild ) <= 1 ) { - - /* delete layouts option */ - delete_option( ot_layouts_id() ); - - /* change message */ - $message = 'deleted'; - - } - - /* redirect */ - if ( isset( $_REQUEST['page'] ) && $_REQUEST['page'] == apply_filters( 'ot_theme_options_menu_slug', 'ot-theme-options' ) ) { - $query_args = esc_url_raw( add_query_arg( array( 'settings-updated' => 'layout' ), remove_query_arg( array( 'action', 'message' ), $_POST['_wp_http_referer'] ) ) ); - } else { - $query_args = esc_url_raw( add_query_arg( array( 'action' => 'save-layouts', 'message' => $message ), $_POST['_wp_http_referer'] ) ); - } - wp_redirect( $query_args ); - exit; - - } - - return false; - - } - + /** + * Save layouts array before the screen is displayed. + * + * @return bool Returns false or redirects. + * + * @access public + * @since 2.0 + */ + function ot_modify_layouts() { + + // Check and verify modify layouts nonce. + if ( isset( $_POST['option_tree_modify_layouts_nonce'] ) && wp_verify_nonce( $_POST['option_tree_modify_layouts_nonce'], 'option_tree_modify_layouts_form' ) ) { // phpcs:ignore + + // Previous layouts value. + $option_tree_layouts = get_option( ot_layouts_id() ); + + // New layouts value. + $layouts = isset( $_POST[ ot_layouts_id() ] ) ? $_POST[ ot_layouts_id() ] : ''; // phpcs:ignore + + // Rebuild layout array. + $rebuild = array(); + + // Validate layouts. + if ( is_array( $layouts ) && ! empty( $layouts ) ) { + + // Setup active layout. + if ( isset( $layouts['active_layout'] ) && ! empty( $layouts['active_layout'] ) ) { + $rebuild['active_layout'] = $layouts['active_layout']; + } + + // Add new and overwrite active layout. + if ( isset( $layouts['_add_new_layout_'] ) && ! empty( $layouts['_add_new_layout_'] ) ) { + $rebuild['active_layout'] = ot_sanitize_layout_id( $layouts['_add_new_layout_'] ); + $rebuild[ $rebuild['active_layout'] ] = ot_encode( get_option( ot_options_id(), array() ) ); + } + + $first_layout = ''; + + // Loop through layouts. + foreach ( $layouts as $key => $layout ) { + + // Skip over active layout key. + if ( 'active_layout' === $key ) { + continue; + } + + // Check if the key exists then set value. + if ( isset( $option_tree_layouts[ $key ] ) && ! empty( $option_tree_layouts[ $key ] ) ) { + $rebuild[ $key ] = $option_tree_layouts[ $key ]; + if ( '' === $first_layout ) { + $first_layout = $key; + } + } + } + + if ( isset( $rebuild['active_layout'] ) && ! isset( $rebuild[ $rebuild['active_layout'] ] ) && ! empty( $first_layout ) ) { + $rebuild['active_layout'] = $first_layout; + } + } + + // Default message. + $message = 'failed'; + + // Save & show success message. + if ( is_array( $rebuild ) && 1 < count( $rebuild ) ) { + + $options = ot_decode( $rebuild[ $rebuild['active_layout'] ] ); + + if ( $options ) { + + $options_safe = array(); + + // Get settings array. + $settings = get_option( ot_settings_id() ); + + // Has options. + if ( is_array( $options ) ) { + + // Validate options. + if ( is_array( $settings ) ) { + foreach ( $settings['settings'] as $setting ) { + if ( isset( $options[ $setting['id'] ] ) ) { + $options_safe[ $setting['id'] ] = ot_validate_setting( wp_unslash( $options[ $setting['id'] ] ), $setting['type'], $setting['id'] ); + } + } + } + + // Execute the action hook and pass the theme options to it. + do_action( 'ot_before_theme_options_save', $options_safe ); + + update_option( ot_options_id(), $options_safe ); + } + } + + // Rebuild the layouts. + update_option( ot_layouts_id(), $rebuild ); + + // Change message. + $message = 'success'; + } elseif ( 1 >= count( $rebuild ) ) { + + // Delete layouts option. + delete_option( ot_layouts_id() ); + + // Change message. + $message = 'deleted'; + } + + // Redirect. + if ( isset( $_REQUEST['page'] ) && apply_filters( 'ot_theme_options_menu_slug', 'ot-theme-options' ) === $_REQUEST['page'] ) { + $query_args = esc_url_raw( + add_query_arg( + array( + 'settings-updated' => 'layout', + ), + remove_query_arg( + array( + 'action', + 'message', + ), + wp_get_referer() + ) + ) + ); + } else { + $query_args = esc_url_raw( + add_query_arg( + array( + 'action' => 'save-layouts', + 'message' => $message, + ), + wp_get_referer() + ) + ); + } + wp_safe_redirect( $query_args ); + exit; + } + + return false; + } } -/** - * Helper function to display alert messages. - * - * @param array Page array - * @return mixed - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_alert_message' ) ) { - function ot_alert_message( $page = array() ) { - - if ( empty( $page ) ) - return false; - - $before = apply_filters( 'ot_before_page_messages', '', $page ); - - if ( $before ) { - return $before; - } - - $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : ''; - $message = isset( $_REQUEST['message'] ) ? $_REQUEST['message'] : ''; - $updated = isset( $_REQUEST['settings-updated'] ) ? $_REQUEST['settings-updated'] : ''; - - if ( $action == 'save-settings' ) { - - if ( $message == 'success' ) { - - return '

' . __( 'Settings updated.', 'option-tree' ) . '

'; - - } else if ( $message == 'failed' ) { - - return '

' . __( 'Settings could not be saved.', 'option-tree' ) . '

'; - - } - - } else if ( $action == 'import-xml' || $action == 'import-settings' ) { - - if ( $message == 'success' ) { - - return '

' . __( 'Settings Imported.', 'option-tree' ) . '

'; - - } else if ( $message == 'failed' ) { - - return '

' . __( 'Settings could not be imported.', 'option-tree' ) . '

'; - - } - } else if ( $action == 'import-data' ) { - - if ( $message == 'success' ) { - - return '

' . __( 'Data Imported.', 'option-tree' ) . '

'; - - } else if ( $message == 'failed' ) { - - return '

' . __( 'Data could not be imported.', 'option-tree' ) . '

'; - - } - - } else if ( $action == 'import-layouts' ) { - - if ( $message == 'success' ) { - - return '

' . __( 'Layouts Imported.', 'option-tree' ) . '

'; - - } else if ( $message == 'failed' ) { - - return '

' . __( 'Layouts could not be imported.', 'option-tree' ) . '

'; - - } - - } else if ( $action == 'save-layouts' ) { - - if ( $message == 'success' ) { - - return '

' . __( 'Layouts Updated.', 'option-tree' ) . '

'; - - } else if ( $message == 'failed' ) { - - return '

' . __( 'Layouts could not be updated.', 'option-tree' ) . '

'; - - } else if ( $message == 'deleted' ) { - - return '

' . __( 'Layouts have been deleted.', 'option-tree' ) . '

'; - - } - - } else if ( $updated == 'layout' ) { - - return '

' . __( 'Layout activated.', 'option-tree' ) . '

'; - - } else if ( $action == 'reset' ) { - - return '

' . $page['reset_message'] . '

'; - - } - - do_action( 'ot_custom_page_messages', $page ); - - if ( $updated == 'true' ) { - - return '

' . $page['updated_message'] . '

'; - - } - - return false; - - } - + /** + * Helper function to display alert messages. + * + * @param array $page Page array. + * @return mixed + * + * @access public + * @since 2.0 + */ + function ot_alert_message( $page = array() ) { + + if ( empty( $page ) ) { + return false; + } + + $before = apply_filters( 'ot_before_page_messages', '', $page ); + + if ( $before ) { + return $before; + } + + $action = isset( $_REQUEST['action'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ) : ''; // phpcs:ignore + $message = isset( $_REQUEST['message'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['message'] ) ) : ''; // phpcs:ignore + $updated = isset( $_REQUEST['settings-updated'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['settings-updated'] ) ) : ''; // phpcs:ignore + + if ( 'save-settings' === $action ) { + + if ( 'success' === $message ) { + + return '

' . esc_html__( 'Settings updated.', 'option-tree' ) . '

'; + + } elseif ( 'failed' === $message ) { + + return '

' . esc_html__( 'Settings could not be saved.', 'option-tree' ) . '

'; + + } + } elseif ( 'import-xml' === $action || 'import-settings' === $action ) { + + if ( 'success' === $message ) { + + return '

' . esc_html__( 'Settings Imported.', 'option-tree' ) . '

'; + + } elseif ( 'failed' === $message ) { + + return '

' . esc_html__( 'Settings could not be imported.', 'option-tree' ) . '

'; + + } + } elseif ( 'import-data' === $action ) { + + if ( 'success' === $message ) { + + return '

' . esc_html__( 'Data Imported.', 'option-tree' ) . '

'; + + } elseif ( 'failed' === $message ) { + + return '

' . esc_html__( 'Data could not be imported.', 'option-tree' ) . '

'; + + } + } elseif ( 'import-layouts' === $action ) { + + if ( 'success' === $message ) { + + return '

' . esc_html__( 'Layouts Imported.', 'option-tree' ) . '

'; + + } elseif ( 'failed' === $message ) { + + return '

' . esc_html__( 'Layouts could not be imported.', 'option-tree' ) . '

'; + + } + } elseif ( 'save-layouts' === $action ) { + + if ( 'success' === $message ) { + + return '

' . esc_html__( 'Layouts Updated.', 'option-tree' ) . '

'; + + } elseif ( 'failed' === $message ) { + + return '

' . esc_html__( 'Layouts could not be updated.', 'option-tree' ) . '

'; + + } elseif ( 'deleted' === $message ) { + + return '

' . esc_html__( 'Layouts have been deleted.', 'option-tree' ) . '

'; + + } + } elseif ( 'layout' === $updated ) { + + return '

' . esc_html__( 'Layout activated.', 'option-tree' ) . '

'; + + } elseif ( 'reset' === $action ) { + + return '

' . $page['reset_message'] . '

'; + + } + + do_action( 'ot_custom_page_messages', $page ); + + if ( 'true' === $updated || true === $updated ) { + return '

' . $page['updated_message'] . '

'; + } + + return false; + } } -/** - * Setup the default option types. - * - * The returned option types are filterable so you can add your own. - * This is not a task for a beginner as you'll need to add the function - * that displays the option to the user and validate the saved data. - * - * @return array - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_option_types_array' ) ) { - function ot_option_types_array() { - - return apply_filters( 'ot_option_types_array', array( - 'background' => __('Background', 'option-tree'), - 'border' => __('Border', 'option-tree'), - 'box-shadow' => __('Box Shadow', 'option-tree'), - 'category-checkbox' => __('Category Checkbox', 'option-tree'), - 'category-select' => __('Category Select', 'option-tree'), - 'checkbox' => __('Checkbox', 'option-tree'), - 'colorpicker' => __('Colorpicker', 'option-tree'), - 'colorpicker-opacity' => __('Colorpicker Opacity', 'option-tree'), - 'css' => __('CSS', 'option-tree'), - 'custom-post-type-checkbox' => __('Custom Post Type Checkbox', 'option-tree'), - 'custom-post-type-select' => __('Custom Post Type Select', 'option-tree'), - 'date-picker' => __('Date Picker', 'option-tree'), - 'date-time-picker' => __('Date Time Picker', 'option-tree'), - 'dimension' => __('Dimension', 'option-tree'), - 'gallery' => __('Gallery', 'option-tree'), - 'google-fonts' => __('Google Fonts', 'option-tree'), - 'javascript' => __('JavaScript', 'option-tree'), - 'link-color' => __('Link Color', 'option-tree'), - 'list-item' => __('List Item', 'option-tree'), - 'measurement' => __('Measurement', 'option-tree'), - 'numeric-slider' => __('Numeric Slider', 'option-tree'), - 'on-off' => __('On/Off', 'option-tree'), - 'page-checkbox' => __('Page Checkbox', 'option-tree'), - 'page-select' => __('Page Select', 'option-tree'), - 'post-checkbox' => __('Post Checkbox', 'option-tree'), - 'post-select' => __('Post Select', 'option-tree'), - 'radio' => __('Radio', 'option-tree'), - 'radio-image' => __('Radio Image', 'option-tree'), - 'select' => __('Select', 'option-tree'), - 'sidebar-select' => __('Sidebar Select', 'option-tree'), - 'slider' => __('Slider', 'option-tree'), - 'social-links' => __('Social Links', 'option-tree'), - 'spacing' => __('Spacing', 'option-tree'), - 'tab' => __('Tab', 'option-tree'), - 'tag-checkbox' => __('Tag Checkbox', 'option-tree'), - 'tag-select' => __('Tag Select', 'option-tree'), - 'taxonomy-checkbox' => __('Taxonomy Checkbox', 'option-tree'), - 'taxonomy-select' => __('Taxonomy Select', 'option-tree'), - 'text' => __('Text', 'option-tree'), - 'textarea' => __('Textarea', 'option-tree'), - 'textarea-simple' => __('Textarea Simple', 'option-tree'), - 'textblock' => __('Textblock', 'option-tree'), - 'textblock-titled' => __('Textblock Titled', 'option-tree'), - 'typography' => __('Typography', 'option-tree'), - 'upload' => __('Upload', 'option-tree') - ) ); - - } + /** + * Setup the default option types. + * + * The returned option types are filterable so you can add your own. + * This is not a task for a beginner as you'll need to add the function + * that displays the option to the user and validate the saved data. + * + * @return array + * + * @access public + * @since 2.0 + */ + function ot_option_types_array() { + + return apply_filters( + 'ot_option_types_array', + array( + 'background' => esc_html__( 'Background', 'option-tree' ), + 'border' => esc_html__( 'Border', 'option-tree' ), + 'box-shadow' => esc_html__( 'Box Shadow', 'option-tree' ), + 'category-checkbox' => esc_html__( 'Category Checkbox', 'option-tree' ), + 'category-select' => esc_html__( 'Category Select', 'option-tree' ), + 'checkbox' => esc_html__( 'Checkbox', 'option-tree' ), + 'colorpicker' => esc_html__( 'Colorpicker', 'option-tree' ), + 'colorpicker-opacity' => esc_html__( 'Colorpicker Opacity', 'option-tree' ), + 'css' => esc_html__( 'CSS', 'option-tree' ), + 'custom-post-type-checkbox' => esc_html__( 'Custom Post Type Checkbox', 'option-tree' ), + 'custom-post-type-select' => esc_html__( 'Custom Post Type Select', 'option-tree' ), + 'date-picker' => esc_html__( 'Date Picker', 'option-tree' ), + 'date-time-picker' => esc_html__( 'Date Time Picker', 'option-tree' ), + 'dimension' => esc_html__( 'Dimension', 'option-tree' ), + 'gallery' => esc_html__( 'Gallery', 'option-tree' ), + 'google-fonts' => esc_html__( 'Google Fonts', 'option-tree' ), + 'javascript' => esc_html__( 'JavaScript', 'option-tree' ), + 'link-color' => esc_html__( 'Link Color', 'option-tree' ), + 'list-item' => esc_html__( 'List Item', 'option-tree' ), + 'measurement' => esc_html__( 'Measurement', 'option-tree' ), + 'numeric-slider' => esc_html__( 'Numeric Slider', 'option-tree' ), + 'on-off' => esc_html__( 'On/Off', 'option-tree' ), + 'page-checkbox' => esc_html__( 'Page Checkbox', 'option-tree' ), + 'page-select' => esc_html__( 'Page Select', 'option-tree' ), + 'post-checkbox' => esc_html__( 'Post Checkbox', 'option-tree' ), + 'post-select' => esc_html__( 'Post Select', 'option-tree' ), + 'radio' => esc_html__( 'Radio', 'option-tree' ), + 'radio-image' => esc_html__( 'Radio Image', 'option-tree' ), + 'select' => esc_html__( 'Select', 'option-tree' ), + 'sidebar-select' => esc_html__( 'Sidebar Select', 'option-tree' ), + 'slider' => esc_html__( 'Slider', 'option-tree' ), + 'social-links' => esc_html__( 'Social Links', 'option-tree' ), + 'spacing' => esc_html__( 'Spacing', 'option-tree' ), + 'tab' => esc_html__( 'Tab', 'option-tree' ), + 'tag-checkbox' => esc_html__( 'Tag Checkbox', 'option-tree' ), + 'tag-select' => esc_html__( 'Tag Select', 'option-tree' ), + 'taxonomy-checkbox' => esc_html__( 'Taxonomy Checkbox', 'option-tree' ), + 'taxonomy-select' => esc_html__( 'Taxonomy Select', 'option-tree' ), + 'text' => esc_html__( 'Text', 'option-tree' ), + 'textarea' => esc_html__( 'Textarea', 'option-tree' ), + 'textarea-simple' => esc_html__( 'Textarea Simple', 'option-tree' ), + 'textblock' => esc_html__( 'Textblock', 'option-tree' ), + 'textblock-titled' => esc_html__( 'Textblock Titled', 'option-tree' ), + 'typography' => esc_html__( 'Typography', 'option-tree' ), + 'upload' => esc_html__( 'Upload', 'option-tree' ), + ) + ); + } } -/** - * Map old option types for rebuilding XML and Table data. - * - * @param string $type The old option type - * @return string The new option type - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_map_old_option_types' ) ) { - function ot_map_old_option_types( $type = '' ) { - - if ( ! $type ) - return 'text'; - - $types = array( - 'background' => 'background', - 'category' => 'category-select', - 'categories' => 'category-checkbox', - 'checkbox' => 'checkbox', - 'colorpicker' => 'colorpicker', - 'css' => 'css', - 'custom_post' => 'custom-post-type-select', - 'custom_posts' => 'custom-post-type-checkbox', - 'input' => 'text', - 'image' => 'upload', - 'measurement' => 'measurement', - 'page' => 'page-select', - 'pages' => 'page-checkbox', - 'post' => 'post-select', - 'posts' => 'post-checkbox', - 'radio' => 'radio', - 'select' => 'select', - 'slider' => 'slider', - 'tag' => 'tag-select', - 'tags' => 'tag-checkbox', - 'textarea' => 'textarea', - 'textblock' => 'textblock', - 'typography' => 'typography', - 'upload' => 'upload' - ); - - if ( isset( $types[$type] ) ) - return $types[$type]; - - return false; - - } + /** + * Map old option types for rebuilding XML and Table data. + * + * @param string $type The old option type. + * @return string The new option type + * + * @access public + * @since 2.0 + */ + function ot_map_old_option_types( $type = '' ) { + + if ( empty( $type ) ) { + return 'text'; + } + + $types = array( + 'background' => 'background', + 'category' => 'category-select', + 'categories' => 'category-checkbox', + 'checkbox' => 'checkbox', + 'colorpicker' => 'colorpicker', + 'css' => 'css', + 'custom_post' => 'custom-post-type-select', + 'custom_posts' => 'custom-post-type-checkbox', + 'input' => 'text', + 'image' => 'upload', + 'measurement' => 'measurement', + 'page' => 'page-select', + 'pages' => 'page-checkbox', + 'post' => 'post-select', + 'posts' => 'post-checkbox', + 'radio' => 'radio', + 'select' => 'select', + 'slider' => 'slider', + 'tag' => 'tag-select', + 'tags' => 'tag-checkbox', + 'textarea' => 'textarea', + 'textblock' => 'textblock', + 'typography' => 'typography', + 'upload' => 'upload', + ); + + if ( isset( $types[ $type ] ) ) { + return $types[ $type ]; + } + + return false; + } } -/** - * Filters the typography font-family to add Google fonts dynamically. - * - * @param array $families An array of all recognized font families. - * @param string $field_id ID of the feild being filtered. - * @return array - * - * @access public - * @since 2.5.0 - */ -function ot_google_font_stack( $families, $field_id ) { - - $ot_google_fonts = get_theme_mod( 'ot_google_fonts', array() ); - $ot_set_google_fonts = get_theme_mod( 'ot_set_google_fonts', array() ); - - if ( ! empty( $ot_set_google_fonts ) ) { - foreach( $ot_set_google_fonts as $id => $sets ) { - foreach( $sets as $value ) { - $family = isset( $value['family'] ) ? $value['family'] : ''; - if ( $family && isset( $ot_google_fonts[$family] ) ) { - $spaces = explode(' ', $ot_google_fonts[$family]['family'] ); - $font_stack = count( $spaces ) > 1 ? '"' . $ot_google_fonts[$family]['family'] . '"': $ot_google_fonts[$family]['family']; - $families[$family] = apply_filters( 'ot_google_font_stack', $font_stack, $family, $field_id ); - } - } - } - } - - return $families; +if ( ! function_exists( 'ot_google_font_stack' ) ) { + + /** + * Filters the typography font-family to add Google fonts dynamically. + * + * @param array $families An array of all recognized font families. + * @param string $field_id ID of the field being filtered. + * + * @return array + * + * @access public + * @since 2.5.0 + */ + function ot_google_font_stack( $families, $field_id ) { + + if ( ! is_array( $families ) ) { + return array(); + } + + $ot_google_fonts = get_theme_mod( 'ot_google_fonts', array() ); + $ot_set_google_fonts = get_theme_mod( 'ot_set_google_fonts', array() ); + + if ( ! empty( $ot_set_google_fonts ) ) { + foreach ( $ot_set_google_fonts as $id => $sets ) { + foreach ( $sets as $value ) { + $family = isset( $value['family'] ) ? $value['family'] : ''; + if ( $family && isset( $ot_google_fonts[ $family ] ) ) { + $spaces = explode( ' ', $ot_google_fonts[ $family ]['family'] ); + $font_stack = count( $spaces ) > 1 ? '"' . $ot_google_fonts[ $family ]['family'] . '"' : $ot_google_fonts[ $family ]['family']; + $families[ $family ] = apply_filters( 'ot_google_font_stack', $font_stack, $family, $field_id ); + } + } + } + } + + return $families; + } + + add_filter( 'ot_recognized_font_families', 'ot_google_font_stack', 1, 2 ); } -add_filter( 'ot_recognized_font_families', 'ot_google_font_stack', 1, 2 ); - -/** - * Recognized font families - * - * Returns an array of all recognized font families. - * Keys are intended to be stored in the database - * while values are ready for display in html. - * Renamed in version 2.0 to avoid name collisions. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 1.1.8 - * @updated 2.0 - */ + if ( ! function_exists( 'ot_recognized_font_families' ) ) { - function ot_recognized_font_families( $field_id = '' ) { - - $families = array( - 'arial' => 'Arial', - 'georgia' => 'Georgia', - 'helvetica' => 'Helvetica', - 'palatino' => 'Palatino', - 'tahoma' => 'Tahoma', - 'times' => '"Times New Roman", sans-serif', - 'trebuchet' => 'Trebuchet', - 'verdana' => 'Verdana' - ); - - return apply_filters( 'ot_recognized_font_families', $families, $field_id ); - - } - + /** + * Recognized font families + * + * Returns an array of all recognized font families. + * Keys are intended to be stored in the database + * while values are ready for display in html. + * Renamed in version 2.0 to avoid name collisions. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 1.1.8 + * @updated 2.0 + */ + function ot_recognized_font_families( $field_id ) { + + $families = array( + 'arial' => 'Arial', + 'georgia' => 'Georgia', + 'helvetica' => 'Helvetica', + 'palatino' => 'Palatino', + 'tahoma' => 'Tahoma', + 'times' => '"Times New Roman", sans-serif', + 'trebuchet' => 'Trebuchet', + 'verdana' => 'Verdana', + ); + + return apply_filters( 'ot_recognized_font_families', $families, $field_id ); + } } -/** - * Recognized font sizes - * - * Returns an array of all recognized font sizes. - * - * @uses apply_filters() - * - * @param string $field_id ID that's passed to the filters. - * @return array - * - * @access public - * @since 2.0.12 - */ if ( ! function_exists( 'ot_recognized_font_sizes' ) ) { - function ot_recognized_font_sizes( $field_id ) { - - $range = ot_range( - apply_filters( 'ot_font_size_low_range', 0, $field_id ), - apply_filters( 'ot_font_size_high_range', 150, $field_id ), - apply_filters( 'ot_font_size_range_interval', 1, $field_id ) - ); - - $unit = apply_filters( 'ot_font_size_unit_type', 'px', $field_id ); - - foreach( $range as $k => $v ) { - $range[$k] = $v . $unit; - } - - return apply_filters( 'ot_recognized_font_sizes', $range, $field_id ); - } - + /** + * Recognized font sizes + * + * Returns an array of all recognized font sizes. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 2.0.12 + */ + function ot_recognized_font_sizes( $field_id ) { + + $range = ot_range( + apply_filters( 'ot_font_size_low_range', 0, $field_id ), + apply_filters( 'ot_font_size_high_range', 150, $field_id ), + apply_filters( 'ot_font_size_range_interval', 1, $field_id ) + ); + + $unit = apply_filters( 'ot_font_size_unit_type', 'px', $field_id ); + + foreach ( $range as $k => $v ) { + $range[ $k ] = $v . $unit; + } + + return apply_filters( 'ot_recognized_font_sizes', $range, $field_id ); + } } -/** - * Recognized font styles - * - * Returns an array of all recognized font styles. - * Renamed in version 2.0 to avoid name collisions. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 1.1.8 - * @updated 2.0 - */ if ( ! function_exists( 'ot_recognized_font_styles' ) ) { - function ot_recognized_font_styles( $field_id = '' ) { - - return apply_filters( 'ot_recognized_font_styles', array( - 'normal' => 'Normal', - 'italic' => 'Italic', - 'oblique' => 'Oblique', - 'inherit' => 'Inherit' - ), $field_id ); - - } - + /** + * Recognized font styles + * + * Returns an array of all recognized font styles. + * Renamed in version 2.0 to avoid name collisions. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 1.1.8 + * @updated 2.0 + */ + function ot_recognized_font_styles( $field_id ) { + + return apply_filters( + 'ot_recognized_font_styles', + array( + 'normal' => 'Normal', + 'italic' => 'Italic', + 'oblique' => 'Oblique', + 'inherit' => 'Inherit', + ), + $field_id + ); + } } -/** - * Recognized font variants - * - * Returns an array of all recognized font variants. - * Renamed in version 2.0 to avoid name collisions. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 1.1.8 - * @updated 2.0 - */ if ( ! function_exists( 'ot_recognized_font_variants' ) ) { - function ot_recognized_font_variants( $field_id = '' ) { - - return apply_filters( 'ot_recognized_font_variants', array( - 'normal' => 'Normal', - 'small-caps' => 'Small Caps', - 'inherit' => 'Inherit' - ), $field_id ); - - } - + /** + * Recognized font variants + * + * Returns an array of all recognized font variants. + * Renamed in version 2.0 to avoid name collisions. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 1.1.8 + * @updated 2.0 + */ + function ot_recognized_font_variants( $field_id ) { + + return apply_filters( + 'ot_recognized_font_variants', + array( + 'normal' => 'Normal', + 'small-caps' => 'Small Caps', + 'inherit' => 'Inherit', + ), + $field_id + ); + } } -/** - * Recognized font weights - * - * Returns an array of all recognized font weights. - * Renamed in version 2.0 to avoid name collisions. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 1.1.8 - * @updated 2.0 - */ if ( ! function_exists( 'ot_recognized_font_weights' ) ) { - function ot_recognized_font_weights( $field_id = '' ) { - - return apply_filters( 'ot_recognized_font_weights', array( - 'normal' => 'Normal', - 'bold' => 'Bold', - 'bolder' => 'Bolder', - 'lighter' => 'Lighter', - '100' => '100', - '200' => '200', - '300' => '300', - '400' => '400', - '500' => '500', - '600' => '600', - '700' => '700', - '800' => '800', - '900' => '900', - 'inherit' => 'Inherit' - ), $field_id ); - - } - + /** + * Recognized font weights + * + * Returns an array of all recognized font weights. + * Renamed in version 2.0 to avoid name collisions. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 1.1.8 + * @updated 2.0 + */ + function ot_recognized_font_weights( $field_id ) { + + return apply_filters( + 'ot_recognized_font_weights', + array( + 'normal' => 'Normal', + 'bold' => 'Bold', + 'bolder' => 'Bolder', + 'lighter' => 'Lighter', + '100' => '100', + '200' => '200', + '300' => '300', + '400' => '400', + '500' => '500', + '600' => '600', + '700' => '700', + '800' => '800', + '900' => '900', + 'inherit' => 'Inherit', + ), + $field_id + ); + } } -/** - * Recognized letter spacing - * - * Returns an array of all recognized line heights. - * - * @uses apply_filters() - * - * @param string $field_id ID that's passed to the filters. - * @return array - * - * @access public - * @since 2.0.12 - */ if ( ! function_exists( 'ot_recognized_letter_spacing' ) ) { - function ot_recognized_letter_spacing( $field_id ) { - - $range = ot_range( - apply_filters( 'ot_letter_spacing_low_range', -0.1, $field_id ), - apply_filters( 'ot_letter_spacing_high_range', 0.1, $field_id ), - apply_filters( 'ot_letter_spacing_range_interval', 0.01, $field_id ) - ); - - $unit = apply_filters( 'ot_letter_spacing_unit_type', 'em', $field_id ); - - foreach( $range as $k => $v ) { - $range[$k] = $v . $unit; - } - - return apply_filters( 'ot_recognized_letter_spacing', $range, $field_id ); - } - + /** + * Recognized letter spacing + * + * Returns an array of all recognized line heights. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 2.0.12 + */ + function ot_recognized_letter_spacing( $field_id ) { + + $range = ot_range( + apply_filters( 'ot_letter_spacing_low_range', -0.1, $field_id ), + apply_filters( 'ot_letter_spacing_high_range', 0.1, $field_id ), + apply_filters( 'ot_letter_spacing_range_interval', 0.01, $field_id ) + ); + + $unit = apply_filters( 'ot_letter_spacing_unit_type', 'em', $field_id ); + + foreach ( $range as $k => $v ) { + $range[ $k ] = $v . $unit; + } + + return apply_filters( 'ot_recognized_letter_spacing', $range, $field_id ); + } } -/** - * Recognized line heights - * - * Returns an array of all recognized line heights. - * - * @uses apply_filters() - * - * @param string $field_id ID that's passed to the filters. - * @return array - * - * @access public - * @since 2.0.12 - */ if ( ! function_exists( 'ot_recognized_line_heights' ) ) { - function ot_recognized_line_heights( $field_id ) { - - $range = ot_range( - apply_filters( 'ot_line_height_low_range', 0, $field_id ), - apply_filters( 'ot_line_height_high_range', 150, $field_id ), - apply_filters( 'ot_line_height_range_interval', 1, $field_id ) - ); - - $unit = apply_filters( 'ot_line_height_unit_type', 'px', $field_id ); - - foreach( $range as $k => $v ) { - $range[$k] = $v . $unit; - } - - return apply_filters( 'ot_recognized_line_heights', $range, $field_id ); - } - + /** + * Recognized line heights + * + * Returns an array of all recognized line heights. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 2.0.12 + */ + function ot_recognized_line_heights( $field_id ) { + + $range = ot_range( + apply_filters( 'ot_line_height_low_range', 0, $field_id ), + apply_filters( 'ot_line_height_high_range', 150, $field_id ), + apply_filters( 'ot_line_height_range_interval', 1, $field_id ) + ); + + $unit = apply_filters( 'ot_line_height_unit_type', 'px', $field_id ); + + foreach ( $range as $k => $v ) { + $range[ $k ] = $v . $unit; + } + + return apply_filters( 'ot_recognized_line_heights', $range, $field_id ); + } } -/** - * Recognized text decorations - * - * Returns an array of all recognized text decorations. - * Keys are intended to be stored in the database - * while values are ready for display in html. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 2.0.10 - */ if ( ! function_exists( 'ot_recognized_text_decorations' ) ) { - - function ot_recognized_text_decorations( $field_id = '' ) { - - return apply_filters( 'ot_recognized_text_decorations', array( - 'blink' => 'Blink', - 'inherit' => 'Inherit', - 'line-through' => 'Line Through', - 'none' => 'None', - 'overline' => 'Overline', - 'underline' => 'Underline' - ), $field_id ); - - } - + + /** + * Recognized text decorations + * + * Returns an array of all recognized text decorations. + * Keys are intended to be stored in the database + * while values are ready for display in html. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 2.0.10 + */ + function ot_recognized_text_decorations( $field_id ) { + + return apply_filters( + 'ot_recognized_text_decorations', + array( + 'blink' => 'Blink', + 'inherit' => 'Inherit', + 'line-through' => 'Line Through', + 'none' => 'None', + 'overline' => 'Overline', + 'underline' => 'Underline', + ), + $field_id + ); + } } -/** - * Recognized text transformations - * - * Returns an array of all recognized text transformations. - * Keys are intended to be stored in the database - * while values are ready for display in html. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 2.0.10 - */ if ( ! function_exists( 'ot_recognized_text_transformations' ) ) { - - function ot_recognized_text_transformations( $field_id = '' ) { - - return apply_filters( 'ot_recognized_text_transformations', array( - 'capitalize' => 'Capitalize', - 'inherit' => 'Inherit', - 'lowercase' => 'Lowercase', - 'none' => 'None', - 'uppercase' => 'Uppercase' - ), $field_id ); - - } - + + /** + * Recognized text transformations + * + * Returns an array of all recognized text transformations. + * Keys are intended to be stored in the database + * while values are ready for display in html. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 2.0.10 + */ + function ot_recognized_text_transformations( $field_id ) { + + return apply_filters( + 'ot_recognized_text_transformations', + array( + 'capitalize' => 'Capitalize', + 'inherit' => 'Inherit', + 'lowercase' => 'Lowercase', + 'none' => 'None', + 'uppercase' => 'Uppercase', + ), + $field_id + ); + } } -/** - * Recognized background repeat - * - * Returns an array of all recognized background repeat values. - * Renamed in version 2.0 to avoid name collisions. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 1.1.8 - * @updated 2.0 - */ if ( ! function_exists( 'ot_recognized_background_repeat' ) ) { - - function ot_recognized_background_repeat( $field_id = '' ) { - - return apply_filters( 'ot_recognized_background_repeat', array( - 'no-repeat' => 'No Repeat', - 'repeat' => 'Repeat All', - 'repeat-x' => 'Repeat Horizontally', - 'repeat-y' => 'Repeat Vertically', - 'inherit' => 'Inherit' - ), $field_id ); - - } - + + /** + * Recognized background repeat + * + * Returns an array of all recognized background repeat values. + * Renamed in version 2.0 to avoid name collisions. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 1.1.8 + * @updated 2.0 + */ + function ot_recognized_background_repeat( $field_id ) { + + return apply_filters( + 'ot_recognized_background_repeat', + array( + 'no-repeat' => 'No Repeat', + 'repeat' => 'Repeat All', + 'repeat-x' => 'Repeat Horizontally', + 'repeat-y' => 'Repeat Vertically', + 'inherit' => 'Inherit', + ), + $field_id + ); + } } -/** - * Recognized background attachment - * - * Returns an array of all recognized background attachment values. - * Renamed in version 2.0 to avoid name collisions. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 1.1.8 - * @updated 2.0 - */ if ( ! function_exists( 'ot_recognized_background_attachment' ) ) { - function ot_recognized_background_attachment( $field_id = '' ) { - - return apply_filters( 'ot_recognized_background_attachment', array( - "fixed" => "Fixed", - "scroll" => "Scroll", - "inherit" => "Inherit" - ), $field_id ); - - } - + /** + * Recognized background attachment + * + * Returns an array of all recognized background attachment values. + * Renamed in version 2.0 to avoid name collisions. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 1.1.8 + * @updated 2.0 + */ + function ot_recognized_background_attachment( $field_id ) { + + return apply_filters( + 'ot_recognized_background_attachment', + array( + 'fixed' => 'Fixed', + 'scroll' => 'Scroll', + 'inherit' => 'Inherit', + ), + $field_id + ); + } } -/** - * Recognized background position - * - * Returns an array of all recognized background position values. - * Renamed in version 2.0 to avoid name collisions. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 1.1.8 - * @updated 2.0 - */ if ( ! function_exists( 'ot_recognized_background_position' ) ) { - function ot_recognized_background_position( $field_id = '' ) { - - return apply_filters( 'ot_recognized_background_position', array( - "left top" => "Left Top", - "left center" => "Left Center", - "left bottom" => "Left Bottom", - "center top" => "Center Top", - "center center" => "Center Center", - "center bottom" => "Center Bottom", - "right top" => "Right Top", - "right center" => "Right Center", - "right bottom" => "Right Bottom" - ), $field_id ); - - } - + /** + * Recognized background position + * + * Returns an array of all recognized background position values. + * Renamed in version 2.0 to avoid name collisions. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 1.1.8 + * @updated 2.0 + */ + function ot_recognized_background_position( $field_id ) { + + return apply_filters( + 'ot_recognized_background_position', + array( + 'left top' => 'Left Top', + 'left center' => 'Left Center', + 'left bottom' => 'Left Bottom', + 'center top' => 'Center Top', + 'center center' => 'Center Center', + 'center bottom' => 'Center Bottom', + 'right top' => 'Right Top', + 'right center' => 'Right Center', + 'right bottom' => 'Right Bottom', + ), + $field_id + ); + + } } -/** - * Border Styles - * - * Returns an array of all available style types. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 2.5.0 - */ if ( ! function_exists( 'ot_recognized_border_style_types' ) ) { - function ot_recognized_border_style_types( $field_id = '' ) { - - return apply_filters( 'ot_recognized_border_style_types', array( - 'hidden' => 'Hidden', - 'dashed' => 'Dashed', - 'solid' => 'Solid', - 'double' => 'Double', - 'groove' => 'Groove', - 'ridge' => 'Ridge', - 'inset' => 'Inset', - 'outset' => 'Outset', - ), $field_id ); - - } - -} - -/** - * Border Units - * - * Returns an array of all available unit types. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 2.5.0 - */ -if ( ! function_exists( 'ot_recognized_border_unit_types' ) ) { - - function ot_recognized_border_unit_types( $field_id = '' ) { - - return apply_filters( 'ot_recognized_border_unit_types', array( - 'px' => 'px', - '%' => '%', - 'em' => 'em', - 'pt' => 'pt' - ), $field_id ); - - } - + /** + * Returns an array of all available border style types. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 2.5.0 + */ + function ot_recognized_border_style_types( $field_id ) { + + return apply_filters( + 'ot_recognized_border_style_types', + array( + 'hidden' => 'Hidden', + 'dashed' => 'Dashed', + 'solid' => 'Solid', + 'double' => 'Double', + 'groove' => 'Groove', + 'ridge' => 'Ridge', + 'inset' => 'Inset', + 'outset' => 'Outset', + ), + $field_id + ); + + } } -/** - * Dimension Units - * - * Returns an array of all available unit types. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 2.5.0 - */ -if ( ! function_exists( 'ot_recognized_dimension_unit_types' ) ) { - - function ot_recognized_dimension_unit_types( $field_id = '' ) { - - return apply_filters( 'ot_recognized_dimension_unit_types', array( - 'px' => 'px', - '%' => '%', - 'em' => 'em', - 'pt' => 'pt' - ), $field_id ); - - } - +if ( ! function_exists( 'ot_recognized_border_unit_types' ) ) { + + /** + * Returns an array of all available border unit types. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 2.5.0 + */ + function ot_recognized_border_unit_types( $field_id ) { + + return apply_filters( + 'ot_recognized_border_unit_types', + array( + 'px' => 'px', + '%' => '%', + 'em' => 'em', + 'pt' => 'pt', + ), + $field_id + ); + } } -/** - * Spacing Units - * - * Returns an array of all available unit types. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 2.5.0 - */ +if ( ! function_exists( 'ot_recognized_dimension_unit_types' ) ) { + + /** + * Returns an array of all available dimension unit types. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 2.5.0 + */ + function ot_recognized_dimension_unit_types( $field_id = '' ) { + + return apply_filters( + 'ot_recognized_dimension_unit_types', + array( + 'px' => 'px', + '%' => '%', + 'em' => 'em', + 'pt' => 'pt', + ), + $field_id + ); + } +} + if ( ! function_exists( 'ot_recognized_spacing_unit_types' ) ) { - function ot_recognized_spacing_unit_types( $field_id = '' ) { - - return apply_filters( 'ot_recognized_spacing_unit_types', array( - 'px' => 'px', - '%' => '%', - 'em' => 'em', - 'pt' => 'pt' - ), $field_id ); - - } - + /** + * Returns an array of all available spacing unit types. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 2.5.0 + */ + function ot_recognized_spacing_unit_types( $field_id ) { + + return apply_filters( + 'ot_recognized_spacing_unit_types', + array( + 'px' => 'px', + '%' => '%', + 'em' => 'em', + 'pt' => 'pt', + ), + $field_id + ); + + } } -/** - * Recognized Google font families - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 2.5.0 - */ if ( ! function_exists( 'ot_recognized_google_font_families' ) ) { - function ot_recognized_google_font_families( $field_id ) { - - $families = array(); - $ot_google_fonts = get_theme_mod( 'ot_google_fonts', array() ); - - // Forces an array rebuild when we sitch themes - if ( empty( $ot_google_fonts ) ) { - $ot_google_fonts = ot_fetch_google_fonts( true, true ); - } - - foreach( (array) $ot_google_fonts as $key => $item ) { - - if ( isset( $item['family'] ) ) { - - $families[ $key ] = $item['family']; - - } - - } - - return apply_filters( 'ot_recognized_google_font_families', $families, $field_id ); - - } - + /** + * Recognized Google font families + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 2.5.0 + */ + function ot_recognized_google_font_families( $field_id ) { + + $families = array(); + $ot_google_fonts = get_theme_mod( 'ot_google_fonts', array() ); + + // Forces an array rebuild when we switch themes. + if ( empty( $ot_google_fonts ) ) { + $ot_google_fonts = ot_fetch_google_fonts( true, true ); + } + + foreach ( (array) $ot_google_fonts as $key => $item ) { + + if ( isset( $item['family'] ) ) { + $families[ $key ] = $item['family']; + } + } + + return apply_filters( 'ot_recognized_google_font_families', $families, $field_id ); + } } -/** - * Recognized Google font variants - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 2.5.0 - */ if ( ! function_exists( 'ot_recognized_google_font_variants' ) ) { - function ot_recognized_google_font_variants( $field_id, $family ) { - - $variants = array(); - $ot_google_fonts = get_theme_mod( 'ot_google_fonts', array() ); - - if ( isset( $ot_google_fonts[ $family ]['variants'] ) ) { - - $variants = $ot_google_fonts[ $family ]['variants']; - - } - - return apply_filters( 'ot_recognized_google_font_variants', $variants, $field_id, $family ); - - } - + /** + * Recognized Google font variants + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * @param string $family The font family. + * + * @return array + * + * @access public + * @since 2.5.0 + */ + function ot_recognized_google_font_variants( $field_id, $family ) { + + $variants = array(); + $ot_google_fonts = get_theme_mod( 'ot_google_fonts', array() ); + + if ( isset( $ot_google_fonts[ $family ]['variants'] ) ) { + $variants = $ot_google_fonts[ $family ]['variants']; + } + + return apply_filters( 'ot_recognized_google_font_variants', $variants, $field_id, $family ); + } } -/** - * Recognized Google font subsets - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 2.5.0 - */ if ( ! function_exists( 'ot_recognized_google_font_subsets' ) ) { - function ot_recognized_google_font_subsets( $field_id, $family ) { - - $subsets = array(); - $ot_google_fonts = get_theme_mod( 'ot_google_fonts', array() ); - - if ( isset( $ot_google_fonts[ $family ]['subsets'] ) ) { - - $subsets = $ot_google_fonts[ $family ]['subsets']; - - } - - return apply_filters( 'ot_recognized_google_font_subsets', $subsets, $field_id, $family ); - - } - + /** + * Recognized Google font subsets + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * @param string $family The font family. + * + * @return array + * + * @access public + * @since 2.5.0 + */ + function ot_recognized_google_font_subsets( $field_id, $family ) { + + $subsets = array(); + $ot_google_fonts = get_theme_mod( 'ot_google_fonts', array() ); + + if ( isset( $ot_google_fonts[ $family ]['subsets'] ) ) { + $subsets = $ot_google_fonts[ $family ]['subsets']; + } + + return apply_filters( 'ot_recognized_google_font_subsets', $subsets, $field_id, $family ); + } } -/** - * Measurement Units - * - * Returns an array of all available unit types. - * Renamed in version 2.0 to avoid name collisions. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 1.1.8 - * @updated 2.0 - */ if ( ! function_exists( 'ot_measurement_unit_types' ) ) { - - function ot_measurement_unit_types( $field_id = '' ) { - - return apply_filters( 'ot_measurement_unit_types', array( - 'px' => 'px', - '%' => '%', - 'em' => 'em', - 'pt' => 'pt' - ), $field_id ); - - } - + + /** + * Measurement Units + * + * Returns an array of all available unit types. + * Renamed in version 2.0 to avoid name collisions. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 1.1.8 + * @since 2.0 + */ + function ot_measurement_unit_types( $field_id = '' ) { + + return apply_filters( + 'ot_measurement_unit_types', + array( + 'px' => 'px', + '%' => '%', + 'em' => 'em', + 'pt' => 'pt', + ), + $field_id + ); + + } } -/** - * Radio Images default array. - * - * Returns an array of all available radio images. - * You can filter this function to change the images - * on a per option basis. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_radio_images' ) ) { - - function ot_radio_images( $field_id = '' ) { - - return apply_filters( 'ot_radio_images', array( - array( - 'value' => 'left-sidebar', - 'label' => __( 'Left Sidebar', 'option-tree' ), - 'src' => OT_URL . 'assets/images/layout/left-sidebar.png' - ), - array( - 'value' => 'right-sidebar', - 'label' => __( 'Right Sidebar', 'option-tree' ), - 'src' => OT_URL . 'assets/images/layout/right-sidebar.png' - ), - array( - 'value' => 'full-width', - 'label' => __( 'Full Width (no sidebar)', 'option-tree' ), - 'src' => OT_URL . 'assets/images/layout/full-width.png' - ), - array( - 'value' => 'dual-sidebar', - 'label' => __( 'Dual Sidebar', 'option-tree' ), - 'src' => OT_URL . 'assets/images/layout/dual-sidebar.png' - ), - array( - 'value' => 'left-dual-sidebar', - 'label' => __( 'Left Dual Sidebar', 'option-tree' ), - 'src' => OT_URL . 'assets/images/layout/left-dual-sidebar.png' - ), - array( - 'value' => 'right-dual-sidebar', - 'label' => __( 'Right Dual Sidebar', 'option-tree' ), - 'src' => OT_URL . 'assets/images/layout/right-dual-sidebar.png' - ) - ), $field_id ); - - } - + + /** + * Radio Images default array. + * + * Returns an array of all available radio images. + * You can filter this function to change the images + * on a per option basis. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 2.0 + */ + function ot_radio_images( $field_id ) { + + return apply_filters( + 'ot_radio_images', + array( + array( + 'value' => 'left-sidebar', + 'label' => esc_html__( 'Left Sidebar', 'option-tree' ), + 'src' => OT_URL . 'assets/images/layout/left-sidebar.png', + ), + array( + 'value' => 'right-sidebar', + 'label' => esc_html__( 'Right Sidebar', 'option-tree' ), + 'src' => OT_URL . 'assets/images/layout/right-sidebar.png', + ), + array( + 'value' => 'full-width', + 'label' => esc_html__( 'Full Width (no sidebar)', 'option-tree' ), + 'src' => OT_URL . 'assets/images/layout/full-width.png', + ), + array( + 'value' => 'dual-sidebar', + 'label' => esc_html__( 'Dual Sidebar', 'option-tree' ), + 'src' => OT_URL . 'assets/images/layout/dual-sidebar.png', + ), + array( + 'value' => 'left-dual-sidebar', + 'label' => esc_html__( 'Left Dual Sidebar', 'option-tree' ), + 'src' => OT_URL . 'assets/images/layout/left-dual-sidebar.png', + ), + array( + 'value' => 'right-dual-sidebar', + 'label' => esc_html__( 'Right Dual Sidebar', 'option-tree' ), + 'src' => OT_URL . 'assets/images/layout/right-dual-sidebar.png', + ), + ), + $field_id + ); + + } } -/** - * Default List Item Settings array. - * - * Returns an array of the default list item settings. - * You can filter this function to change the settings - * on a per option basis. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_list_item_settings' ) ) { - function ot_list_item_settings( $id ) { - - $settings = apply_filters( 'ot_list_item_settings', array( - array( - 'id' => 'image', - 'label' => __( 'Image', 'option-tree' ), - 'desc' => '', - 'std' => '', - 'type' => 'upload', - 'rows' => '', - 'class' => '', - 'post_type' => '', - 'choices' => array() - ), - array( - 'id' => 'link', - 'label' => __( 'Link', 'option-tree' ), - 'desc' => '', - 'std' => '', - 'type' => 'text', - 'rows' => '', - 'class' => '', - 'post_type' => '', - 'choices' => array() - ), - array( - 'id' => 'description', - 'label' => __( 'Description', 'option-tree' ), - 'desc' => '', - 'std' => '', - 'type' => 'textarea-simple', - 'rows' => 10, - 'class' => '', - 'post_type' => '', - 'choices' => array() - ) - ), $id ); - - return $settings; - - } - + /** + * Default List Item Settings array. + * + * Returns an array of the default list item settings. + * You can filter this function to change the settings + * on a per option basis. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 2.0 + */ + function ot_list_item_settings( $field_id ) { + + $settings = apply_filters( + 'ot_list_item_settings', + array( + array( + 'id' => 'image', + 'label' => esc_html__( 'Image', 'option-tree' ), + 'desc' => '', + 'std' => '', + 'type' => 'upload', + 'rows' => '', + 'class' => '', + 'post_type' => '', + 'choices' => array(), + ), + array( + 'id' => 'link', + 'label' => esc_html__( 'Link', 'option-tree' ), + 'desc' => '', + 'std' => '', + 'type' => 'text', + 'rows' => '', + 'class' => '', + 'post_type' => '', + 'choices' => array(), + ), + array( + 'id' => 'description', + 'label' => esc_html__( 'Description', 'option-tree' ), + 'desc' => '', + 'std' => '', + 'type' => 'textarea-simple', + 'rows' => 10, + 'class' => '', + 'post_type' => '', + 'choices' => array(), + ), + ), + $field_id + ); + + return $settings; + } } -/** - * Default Slider Settings array. - * - * Returns an array of the default slider settings. - * You can filter this function to change the settings - * on a per option basis. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_slider_settings' ) ) { - function ot_slider_settings( $id ) { - - $settings = apply_filters( 'image_slider_fields', array( - array( - 'name' => 'image', - 'type' => 'image', - 'label' => __( 'Image', 'option-tree' ), - 'class' => '' - ), - array( - 'name' => 'link', - 'type' => 'text', - 'label' => __( 'Link', 'option-tree' ), - 'class' => '' - ), - array( - 'name' => 'description', - 'type' => 'textarea', - 'label' => __( 'Description', 'option-tree' ), - 'class' => '' - ) - ), $id ); - - /* fix the array keys, values, and just get it 2.0 ready */ - foreach( $settings as $_k => $setting ) { - - foreach( $setting as $s_key => $s_value ) { - - if ( 'name' == $s_key ) { - - $settings[$_k]['id'] = $s_value; - unset($settings[$_k]['name']); - - } else if ( 'type' == $s_key ) { - - if ( 'input' == $s_value ) { - - $settings[$_k]['type'] = 'text'; - - } else if ( 'textarea' == $s_value ) { - - $settings[$_k]['type'] = 'textarea-simple'; - - } else if ( 'image' == $s_value ) { - - $settings[$_k]['type'] = 'upload'; - - } - - } - - } - - } - - return $settings; - - } - -} - -/** - * Default Social Links Settings array. - * - * Returns an array of the default social links settings. - * You can filter this function to change the settings - * on a per option basis. - * - * @uses apply_filters() - * - * @return array - * - * @access public - * @since 2.4.0 - */ -if ( ! function_exists( 'ot_social_links_settings' ) ) { - - function ot_social_links_settings( $id ) { - - $settings = apply_filters( 'ot_social_links_settings', array( - array( - 'id' => 'name', - 'label' => __( 'Name', 'option-tree' ), - 'desc' => __( 'Enter the name of the social website.', 'option-tree' ), - 'std' => '', - 'type' => 'text', - 'class' => 'option-tree-setting-title' - ), - array( - 'id' => 'title', - 'label' => 'Title', - 'desc' => __( 'Enter the text shown in the title attribute of the link.', 'option-tree' ), - 'type' => 'text' - ), - array( - 'id' => 'href', - 'label' => 'Link', - 'desc' => sprintf( __( 'Enter a link to the profile or page on the social website. Remember to add the %s part to the front of the link.', 'option-tree' ), 'http://' ), - 'type' => 'text', - ) - ), $id ); - - return $settings; - - } - + /** + * Default Slider Settings array. + * + * Returns an array of the default slider settings. + * You can filter this function to change the settings + * on a per option basis. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 2.0 + */ + function ot_slider_settings( $field_id ) { + + $settings = apply_filters( + 'image_slider_fields', + array( + array( + 'name' => 'image', + 'type' => 'image', + 'label' => esc_html__( 'Image', 'option-tree' ), + 'class' => '', + ), + array( + 'name' => 'link', + 'type' => 'text', + 'label' => esc_html__( 'Link', 'option-tree' ), + 'class' => '', + ), + array( + 'name' => 'description', + 'type' => 'textarea', + 'label' => esc_html__( 'Description', 'option-tree' ), + 'class' => '', + ), + ), + $field_id + ); + + // Fix the array keys, values, and just get it 2.0 ready. + foreach ( $settings as $_k => $setting ) { + + foreach ( $setting as $s_key => $s_value ) { + + if ( 'name' === $s_key ) { + + $settings[ $_k ]['id'] = $s_value; + unset( $settings[ $_k ]['name'] ); + } elseif ( 'type' === $s_key ) { + + if ( 'input' === $s_value ) { + + $settings[ $_k ]['type'] = 'text'; + } elseif ( 'textarea' === $s_value ) { + + $settings[ $_k ]['type'] = 'textarea-simple'; + } elseif ( 'image' === $s_value ) { + + $settings[ $_k ]['type'] = 'upload'; + } + } + } + } + + return $settings; + } } -/** - * Inserts CSS with field_id markers. - * - * Inserts CSS into a dynamic.css file, placing it between - * BEGIN and END field_id markers. Replaces existing marked info, - * but still retains surrounding data. - * - * @param string $field_id The CSS option field ID. - * @param array $options The current option_tree array. - * @return bool True on write success, false on failure. - * - * @access public - * @since 1.1.8 - * @updated 2.5.3 - */ +if ( ! function_exists( 'ot_social_links_settings' ) ) { + + /** + * Default Social Links Settings array. + * + * Returns an array of the default social links settings. + * You can filter this function to change the settings + * on a per option basis. + * + * @uses apply_filters() + * + * @param string $field_id ID that's passed to the filter. + * + * @return array + * + * @access public + * @since 2.4.0 + */ + function ot_social_links_settings( $field_id ) { + + /* translators: %s: the http protocol */ + $string = esc_html__( 'Enter a link to the profile or page on the social website. Remember to add the %s part to the front of the link.', 'option-tree' ); + $settings = apply_filters( + 'ot_social_links_settings', + array( + array( + 'id' => 'name', + 'label' => esc_html__( 'Name', 'option-tree' ), + 'desc' => esc_html__( 'Enter the name of the social website.', 'option-tree' ), + 'std' => '', + 'type' => 'text', + 'class' => 'option-tree-setting-title', + ), + array( + 'id' => 'title', + 'label' => 'Title', + 'desc' => esc_html__( 'Enter the text shown in the title attribute of the link.', 'option-tree' ), + 'type' => 'text', + ), + array( + 'id' => 'href', + 'label' => 'Link', + 'desc' => sprintf( $string, 'http:// or https://' ), + 'type' => 'text', + ), + ), + $field_id + ); + + return $settings; + } +} + if ( ! function_exists( 'ot_insert_css_with_markers' ) ) { - function ot_insert_css_with_markers( $field_id = '', $insertion = '', $meta = false ) { - - /* missing $field_id or $insertion exit early */ - if ( '' == $field_id || '' == $insertion ) - return; - - /* path to the dynamic.css file */ - $filepath = get_stylesheet_directory() . '/dynamic.css'; - if ( is_multisite() ) { - $multisite_filepath = get_stylesheet_directory() . '/dynamic-' . get_current_blog_id() . '.css'; - if ( file_exists( $multisite_filepath ) ) { - $filepath = $multisite_filepath; - } - } - - /* allow filter on path */ - $filepath = apply_filters( 'css_option_file_path', $filepath, $field_id ); - - /* grab a copy of the paths array */ - $ot_css_file_paths = get_option( 'ot_css_file_paths', array() ); - if ( is_multisite() ) { - $ot_css_file_paths = get_blog_option( get_current_blog_id(), 'ot_css_file_paths', $ot_css_file_paths ); - } - - /* set the path for this field */ - $ot_css_file_paths[$field_id] = $filepath; - - /* update the paths */ - if ( is_multisite() ) { - update_blog_option( get_current_blog_id(), 'ot_css_file_paths', $ot_css_file_paths ); - } else { - update_option( 'ot_css_file_paths', $ot_css_file_paths ); - } - - /* insert CSS into file */ - if ( file_exists( $filepath ) ) { - - $insertion = ot_normalize_css( $insertion ); - $regex = "/{{([a-zA-Z0-9\_\-\#\|\=]+)}}/"; - $marker = $field_id; - - /* Match custom CSS */ - preg_match_all( $regex, $insertion, $matches ); - - /* Loop through CSS */ - foreach( $matches[0] as $option ) { - - $value = ''; - $option_array = explode( '|', str_replace( array( '{{', '}}' ), '', $option ) ); - $option_id = isset( $option_array[0] ) ? $option_array[0] : ''; - $option_key = isset( $option_array[1] ) ? $option_array[1] : ''; - $option_type = ot_get_option_type_by_id( $option_id ); - $fallback = ''; - - // Get the meta array value - if ( $meta ) { - global $post; - - $value = get_post_meta( $post->ID, $option_id, true ); - - // Get the options array value - } else { - - $options = get_option( ot_options_id() ); - - if ( isset( $options[$option_id] ) ) { - - $value = $options[$option_id]; - - } - - } - - // This in an array of values - if ( is_array( $value ) ) { - - if ( empty( $option_key ) ) { - - // Measurement - if ( $option_type == 'measurement' ) { - $unit = ! empty( $value[1] ) ? $value[1] : 'px'; - - // Set $value with measurement properties - if ( isset( $value[0] ) && strlen( $value[0] ) > 0 ) - $value = $value[0].$unit; - - // Border - } else if ( $option_type == 'border' ) { - $border = array(); - - $unit = ! empty( $value['unit'] ) ? $value['unit'] : 'px'; - - if ( isset( $value['width'] ) && strlen( $value['width'] ) > 0 ) - $border[] = $value['width'].$unit; - - if ( ! empty( $value['style'] ) ) - $border[] = $value['style']; - - if ( ! empty( $value['color'] ) ) - $border[] = $value['color']; - - /* set $value with border properties or empty string */ - $value = ! empty( $border ) ? implode( ' ', $border ) : ''; - - // Box Shadow - } else if ( $option_type == 'box-shadow' ) { - - /* set $value with box-shadow properties or empty string */ - $value = ! empty( $value ) ? implode( ' ', $value ) : ''; - - // Dimension - } else if ( $option_type == 'dimension' ) { - $dimension = array(); - - $unit = ! empty( $value['unit'] ) ? $value['unit'] : 'px'; - - if ( isset( $value['width'] ) && strlen( $value['width'] ) > 0 ) - $dimension[] = $value['width'].$unit; - - if ( isset( $value['height'] ) && strlen( $value['height'] ) > 0 ) - $dimension[] = $value['height'].$unit; - - // Set $value with dimension properties or empty string - $value = ! empty( $dimension ) ? implode( ' ', $dimension ) : ''; - - // Spacing - } else if ( $option_type == 'spacing' ) { - $spacing = array(); - - $unit = ! empty( $value['unit'] ) ? $value['unit'] : 'px'; - - if ( isset( $value['top'] ) && strlen( $value['top'] ) > 0 ) - $spacing[] = $value['top'].$unit; - - if ( isset( $value['right'] ) && strlen( $value['right'] ) > 0 ) - $spacing[] = $value['right'].$unit; - - if ( isset( $value['bottom'] ) && strlen( $value['bottom'] ) > 0 ) - $spacing[] = $value['bottom'].$unit; - - if ( isset( $value['left'] ) && strlen( $value['left'] ) > 0 ) - $spacing[] = $value['left'].$unit; - - // Set $value with spacing properties or empty string - $value = ! empty( $spacing ) ? implode( ' ', $spacing ) : ''; - - // Typography - } else if ( $option_type == 'typography' ) { - $font = array(); - - if ( ! empty( $value['font-color'] ) ) - $font[] = "color: " . $value['font-color'] . ";"; - - if ( ! empty( $value['font-family'] ) ) { - foreach ( ot_recognized_font_families( $marker ) as $key => $v ) { - if ( $key == $value['font-family'] ) { - $font[] = "font-family: " . $v . ";"; - } - } - } - - if ( ! empty( $value['font-size'] ) ) - $font[] = "font-size: " . $value['font-size'] . ";"; - - if ( ! empty( $value['font-style'] ) ) - $font[] = "font-style: " . $value['font-style'] . ";"; - - if ( ! empty( $value['font-variant'] ) ) - $font[] = "font-variant: " . $value['font-variant'] . ";"; - - if ( ! empty( $value['font-weight'] ) ) - $font[] = "font-weight: " . $value['font-weight'] . ";"; - - if ( ! empty( $value['letter-spacing'] ) ) - $font[] = "letter-spacing: " . $value['letter-spacing'] . ";"; - - if ( ! empty( $value['line-height'] ) ) - $font[] = "line-height: " . $value['line-height'] . ";"; - - if ( ! empty( $value['text-decoration'] ) ) - $font[] = "text-decoration: " . $value['text-decoration'] . ";"; - - if ( ! empty( $value['text-transform'] ) ) - $font[] = "text-transform: " . $value['text-transform'] . ";"; - - // Set $value with font properties or empty string - $value = ! empty( $font ) ? implode( "\n", $font ) : ''; - - // Background - } else if ( $option_type == 'background' ) { - $bg = array(); - - if ( ! empty( $value['background-color'] ) ) - $bg[] = $value['background-color']; - - if ( ! empty( $value['background-image'] ) ) { - - // If an attachment ID is stored here fetch its URL and replace the value - if ( wp_attachment_is_image( $value['background-image'] ) ) { - - $attachment_data = wp_get_attachment_image_src( $value['background-image'], 'original' ); - - // Check for attachment data - if ( $attachment_data ) { - - $value['background-image'] = $attachment_data[0]; - - } - - } - - $bg[] = 'url("' . $value['background-image'] . '")'; - - } - - if ( ! empty( $value['background-repeat'] ) ) - $bg[] = $value['background-repeat']; - - if ( ! empty( $value['background-attachment'] ) ) - $bg[] = $value['background-attachment']; - - if ( ! empty( $value['background-position'] ) ) - $bg[] = $value['background-position']; - - if ( ! empty( $value['background-size'] ) ) - $size = $value['background-size']; - - // Set $value with background properties or empty string - $value = ! empty( $bg ) ? 'background: ' . implode( " ", $bg ) . ';' : ''; - - if ( isset( $size ) ) { - if ( ! empty( $bg ) ) { - $value.= apply_filters( 'ot_insert_css_with_markers_bg_size_white_space', "\n\x20\x20", $option_id ); - } - $value.= "background-size: $size;"; - } - - } - - } else { - - $value = $value[$option_key]; - - } - - } - - // If an attachment ID is stored here fetch its URL and replace the value - if ( $option_type == 'upload' && wp_attachment_is_image( $value ) ) { - - $attachment_data = wp_get_attachment_image_src( $value, 'original' ); - - // Check for attachment data - if ( $attachment_data ) { - - $value = $attachment_data[0]; - - } - - } - - // Attempt to fallback when `$value` is empty - if ( empty( $value ) ) { - - // We're trying to access a single array key - if ( ! empty( $option_key ) ) { - - // Link Color `inherit` - if ( $option_type == 'link-color' ) { - $fallback = 'inherit'; - } - - } else { - - // Border - if ( $option_type == 'border' ) { - $fallback = 'inherit'; - } - - // Box Shadow - if ( $option_type == 'box-shadow' ) { - $fallback = 'none'; - } - - // Colorpicker - if ( $option_type == 'colorpicker' ) { - $fallback = 'inherit'; - } - - // Colorpicker Opacity - if ( $option_type == 'colorpicker-opacity' ) { - $fallback = 'inherit'; - } - - } - - /** - * Filter the `dynamic.css` fallback value. - * - * @since 2.5.3 - * - * @param string $fallback The default CSS fallback value. - * @param string $option_id The option ID. - * @param string $option_type The option type. - * @param string $option_key The option array key. - */ - $fallback = apply_filters( 'ot_insert_css_with_markers_fallback', $fallback, $option_id, $option_type, $option_key ); - - } - - // Let's fallback! - if ( ! empty( $fallback ) ) { - $value = $fallback; - } - - // Filter the CSS - $value = apply_filters( 'ot_insert_css_with_markers_value', $value, $option_id ); - - // Insert CSS, even if the value is empty - $insertion = stripslashes( str_replace( $option, $value, $insertion ) ); - - } - - // Can't write to the file so we error out - if ( ! is_writable( $filepath ) ) { - add_settings_error( 'option-tree', 'dynamic_css', sprintf( __( 'Unable to write to file %s.', 'option-tree' ), '' . $filepath . '' ), 'error' ); - return false; - } - - // Create array from the lines of code - $markerdata = explode( "\n", implode( '', file( $filepath ) ) ); - - // Can't write to the file return false - if ( ! $f = ot_file_open( $filepath, 'w' ) ) { - return false; - } - - $searching = true; - $foundit = false; - - // Has array of lines - if ( ! empty( $markerdata ) ) { - - // Foreach line of code - foreach( $markerdata as $n => $markerline ) { - - // Found begining of marker, set $searching to false - if ( $markerline == "/* BEGIN {$marker} */" ) - $searching = false; - - // Keep searching each line of CSS - if ( $searching == true ) { - if ( $n + 1 < count( $markerdata ) ) - ot_file_write( $f, "{$markerline}\n" ); - else - ot_file_write( $f, "{$markerline}" ); - } - - // Found end marker write code - if ( $markerline == "/* END {$marker} */" ) { - ot_file_write( $f, "/* BEGIN {$marker} */\n" ); - ot_file_write( $f, "{$insertion}\n" ); - ot_file_write( $f, "/* END {$marker} */\n" ); - $searching = true; - $foundit = true; - } - - } - - } - - // Nothing inserted, write code. DO IT, DO IT! - if ( ! $foundit ) { - ot_file_write( $f, "/* BEGIN {$marker} */\n" ); - ot_file_write( $f, "{$insertion}\n" ); - ot_file_write( $f, "/* END {$marker} */\n" ); - } - - // Close file - ot_file_close( $f ); - return true; - } - - return false; - - } - + /** + * Inserts CSS with field_id markers. + * + * Inserts CSS into a dynamic.css file, placing it between + * BEGIN and END field_id markers. Replaces existing marked info, + * but still retains surrounding data. + * + * @param string $field_id The CSS option field ID. + * @param string $insertion The current option_tree array. + * @param bool $meta Whether or not the value is stored in meta. + * @return bool True on write success, false on failure. + * + * @access public + * @since 1.1.8 + * @updated 2.5.3 + */ + function ot_insert_css_with_markers( $field_id = '', $insertion = '', $meta = false ) { + + // Missing $field_id or $insertion exit early. + if ( '' === $field_id || '' === $insertion ) { + return; + } + + // Path to the dynamic.css file. + $filepath = get_stylesheet_directory() . '/dynamic.css'; + if ( is_multisite() ) { + $multisite_filepath = get_stylesheet_directory() . '/dynamic-' . get_current_blog_id() . '.css'; + if ( file_exists( $multisite_filepath ) ) { + $filepath = $multisite_filepath; + } + } + + // Allow filter on path. + $filepath = apply_filters( 'css_option_file_path', $filepath, $field_id ); + + // Grab a copy of the paths array. + $ot_css_file_paths = get_option( 'ot_css_file_paths', array() ); + if ( is_multisite() ) { + $ot_css_file_paths = get_blog_option( get_current_blog_id(), 'ot_css_file_paths', $ot_css_file_paths ); + } + + // Set the path for this field. + $ot_css_file_paths[ $field_id ] = $filepath; + + /* update the paths */ + if ( is_multisite() ) { + update_blog_option( get_current_blog_id(), 'ot_css_file_paths', $ot_css_file_paths ); + } else { + update_option( 'ot_css_file_paths', $ot_css_file_paths ); + } + + // Remove CSS from file, but ensure the file is actually CSS first. + $file_parts = explode( '.', basename( $filepath ) ); + $file_ext = end( $file_parts ); + if ( is_writeable( $filepath ) && 'css' === $file_ext ) { + + $insertion = ot_normalize_css( $insertion ); + $regex = '/{{([a-zA-Z0-9\_\-\#\|\=]+)}}/'; + $marker = $field_id; + + // Match custom CSS. + preg_match_all( $regex, $insertion, $matches ); + + // Loop through CSS. + foreach ( $matches[0] as $option ) { + + $value = ''; + $option_array = explode( '|', str_replace( array( '{{', '}}' ), '', $option ) ); + $option_id = isset( $option_array[0] ) ? $option_array[0] : ''; + $option_key = isset( $option_array[1] ) ? $option_array[1] : ''; + $option_type = ot_get_option_type_by_id( $option_id ); + $fallback = ''; + + // Get the meta array value. + if ( $meta ) { + global $post; + + $value = get_post_meta( $post->ID, $option_id, true ); + + // Get the options array value. + } else { + $options = get_option( ot_options_id() ); + + if ( isset( $options[ $option_id ] ) ) { + $value = $options[ $option_id ]; + } + } + + // This in an array of values. + if ( is_array( $value ) ) { + + if ( empty( $option_key ) ) { + + // Measurement. + if ( 'measurement' === $option_type ) { + $unit = ! empty( $value[1] ) ? $value[1] : 'px'; + + // Set $value with measurement properties. + if ( isset( $value[0] ) && strlen( $value[0] ) > 0 ) { + $value = $value[0] . $unit; + } + + // Border. + } elseif ( 'border' === $option_type ) { + $border = array(); + + $unit = ! empty( $value['unit'] ) ? $value['unit'] : 'px'; + + if ( isset( $value['width'] ) && strlen( $value['width'] ) > 0 ) { + $border[] = $value['width'] . $unit; + } + + if ( ! empty( $value['style'] ) ) { + $border[] = $value['style']; + } + + if ( ! empty( $value['color'] ) ) { + $border[] = $value['color']; + } + + // Set $value with border properties or empty string. + $value = ! empty( $border ) ? implode( ' ', $border ) : ''; + + // Box Shadow. + } elseif ( 'box-shadow' === $option_type ) { + + $value_safe = array(); + foreach ( $value as $val ) { + if ( ! empty( $val ) ) { + $value_safe[] = $val; + } + } + // Set $value with box-shadow properties or empty string. + $value = ! empty( $value_safe ) ? implode( ' ', $value_safe ) : ''; + + // Dimension. + } elseif ( 'dimension' === $option_type ) { + $dimension = array(); + + $unit = ! empty( $value['unit'] ) ? $value['unit'] : 'px'; + + if ( isset( $value['width'] ) && strlen( $value['width'] ) > 0 ) { + $dimension[] = $value['width'] . $unit; + } + + if ( isset( $value['height'] ) && strlen( $value['height'] ) > 0 ) { + $dimension[] = $value['height'] . $unit; + } + + // Set $value with dimension properties or empty string. + $value = ! empty( $dimension ) ? implode( ' ', $dimension ) : ''; + + // Spacing. + } elseif ( 'spacing' === $option_type ) { + $spacing = array(); + + $unit = ! empty( $value['unit'] ) ? $value['unit'] : 'px'; + + if ( isset( $value['top'] ) && strlen( $value['top'] ) > 0 ) { + $spacing[] = $value['top'] . $unit; + } + + if ( isset( $value['right'] ) && strlen( $value['right'] ) > 0 ) { + $spacing[] = $value['right'] . $unit; + } + + if ( isset( $value['bottom'] ) && strlen( $value['bottom'] ) > 0 ) { + $spacing[] = $value['bottom'] . $unit; + } + + if ( isset( $value['left'] ) && strlen( $value['left'] ) > 0 ) { + $spacing[] = $value['left'] . $unit; + } + + // Set $value with spacing properties or empty string. + $value = ! empty( $spacing ) ? implode( ' ', $spacing ) : ''; + + // Typography. + } elseif ( 'typography' === $option_type ) { + $font = array(); + + if ( ! empty( $value['font-color'] ) ) { + $font[] = 'color: ' . $value['font-color'] . ';'; + } + + if ( ! empty( $value['font-family'] ) ) { + foreach ( ot_recognized_font_families( $marker ) as $key => $v ) { + if ( $key === $value['font-family'] ) { + $font[] = 'font-family: ' . $v . ';'; + } + } + } + + if ( ! empty( $value['font-size'] ) ) { + $font[] = 'font-size: ' . $value['font-size'] . ';'; + } + + if ( ! empty( $value['font-style'] ) ) { + $font[] = 'font-style: ' . $value['font-style'] . ';'; + } + + if ( ! empty( $value['font-variant'] ) ) { + $font[] = 'font-variant: ' . $value['font-variant'] . ';'; + } + + if ( ! empty( $value['font-weight'] ) ) { + $font[] = 'font-weight: ' . $value['font-weight'] . ';'; + } + + if ( ! empty( $value['letter-spacing'] ) ) { + $font[] = 'letter-spacing: ' . $value['letter-spacing'] . ';'; + } + + if ( ! empty( $value['line-height'] ) ) { + $font[] = 'line-height: ' . $value['line-height'] . ';'; + } + + if ( ! empty( $value['text-decoration'] ) ) { + $font[] = 'text-decoration: ' . $value['text-decoration'] . ';'; + } + + if ( ! empty( $value['text-transform'] ) ) { + $font[] = 'text-transform: ' . $value['text-transform'] . ';'; + } + + // Set $value with font properties or empty string. + $value = ! empty( $font ) ? implode( "\n", $font ) : ''; + + // Background. + } elseif ( 'background' === $option_type ) { + $bg = array(); + + if ( ! empty( $value['background-color'] ) ) { + $bg[] = $value['background-color']; + } + + if ( ! empty( $value['background-image'] ) ) { + + // If an attachment ID is stored here fetch its URL and replace the value. + if ( wp_attachment_is_image( $value['background-image'] ) ) { + + $attachment_data = wp_get_attachment_image_src( $value['background-image'], 'original' ); + + // Check for attachment data. + if ( $attachment_data ) { + $value['background-image'] = $attachment_data[0]; + } + } + + $bg[] = 'url("' . $value['background-image'] . '")'; + } + + if ( ! empty( $value['background-repeat'] ) ) { + $bg[] = $value['background-repeat']; + } + + if ( ! empty( $value['background-attachment'] ) ) { + $bg[] = $value['background-attachment']; + } + + if ( ! empty( $value['background-position'] ) ) { + $bg[] = $value['background-position']; + } + + if ( ! empty( $value['background-size'] ) ) { + $size = $value['background-size']; + } + + // Set $value with background properties or empty string. + $value = ! empty( $bg ) ? 'background: ' . implode( ' ', $bg ) . ';' : ''; + + if ( isset( $size ) ) { + if ( ! empty( $bg ) ) { + $value .= apply_filters( 'ot_insert_css_with_markers_bg_size_white_space', "\n\x20\x20", $option_id ); + } + $value .= "background-size: $size;"; + } + } + } elseif ( ! empty( $value[ $option_key ] ) ) { + $value = $value[ $option_key ]; + } + } + + // If an attachment ID is stored here fetch its URL and replace the value. + if ( 'upload' === $option_type && wp_attachment_is_image( $value ) ) { + + $attachment_data = wp_get_attachment_image_src( $value, 'original' ); + + // Check for attachment data. + if ( $attachment_data ) { + $value = $attachment_data[0]; + } + } + + // Attempt to fallback when `$value` is empty. + if ( empty( $value ) ) { + + // We're trying to access a single array key. + if ( ! empty( $option_key ) ) { + + // Link Color `inherit`. + if ( 'link-color' === $option_type ) { + $fallback = 'inherit'; + } + } else { + + // Border. + if ( 'border' === $option_type ) { + $fallback = 'inherit'; + } + + // Box Shadow. + if ( 'box-shadow' === $option_type ) { + $fallback = 'none'; + } + + // Colorpicker. + if ( 'colorpicker' === $option_type ) { + $fallback = 'inherit'; + } + + // Colorpicker Opacity. + if ( 'colorpicker-opacity' === $option_type ) { + $fallback = 'inherit'; + } + } + + /** + * Filter the `dynamic.css` fallback value. + * + * @since 2.5.3 + * + * @param string $fallback The default CSS fallback value. + * @param string $option_id The option ID. + * @param string $option_type The option type. + * @param string $option_key The option array key. + */ + $fallback = apply_filters( 'ot_insert_css_with_markers_fallback', $fallback, $option_id, $option_type, $option_key ); + } + + // Let's fallback! + if ( ! empty( $fallback ) ) { + $value = $fallback; + } + + // Filter the CSS. + $value = apply_filters( 'ot_insert_css_with_markers_value', $value, $option_id ); + + // Insert CSS, even if the value is empty. + $insertion = stripslashes( str_replace( $option, $value, $insertion ) ); + } + + // Can't write to the file so we error out. + if ( ! is_writable( $filepath ) ) { + /* translators: %s: file path */ + $string = esc_html__( 'Unable to write to file %s.', 'option-tree' ); + add_settings_error( 'option-tree', 'dynamic_css', sprintf( $string, '' . $filepath . '' ), 'error' ); + return false; + } + + // Open file. + $f = @fopen( $filepath, 'w' ); // phpcs:ignore + + // Can't write to the file return false. + if ( ! $f ) { + /* translators: %s: file path */ + $string = esc_html__( 'Unable to open the %s file in write mode.', 'option-tree' ); + add_settings_error( 'option-tree', 'dynamic_css', sprintf( $string, '' . $filepath . '' ), 'error' ); + return false; + } + + // Create array from the lines of code. + $markerdata = explode( "\n", implode( '', file( $filepath ) ) ); + + $searching = true; + $foundit = false; + + // Has array of lines. + if ( ! empty( $markerdata ) ) { + + // Foreach line of code. + foreach ( $markerdata as $n => $markerline ) { + + // Found begining of marker, set $searching to false. + if ( "/* BEGIN {$marker} */" === $markerline ) { + $searching = false; + } + + // Keep searching each line of CSS. + if ( true === $searching ) { + if ( $n + 1 < count( $markerdata ) ) { + fwrite( $f, "{$markerline}\n" ); // phpcs:ignore + } else { + fwrite( $f, "{$markerline}" ); // phpcs:ignore + } + } + + // Found end marker write code. + if ( "/* END {$marker} */" === $markerline ) { + fwrite( $f, "/* BEGIN {$marker} */\n" ); // phpcs:ignore + fwrite( $f, "{$insertion}\n" ); // phpcs:ignore + fwrite( $f, "/* END {$marker} */\n" ); // phpcs:ignore + $searching = true; + $foundit = true; + } + } + } + + // Nothing inserted, write code. DO IT, DO IT! + if ( ! $foundit ) { + fwrite( $f, "/* BEGIN {$marker} */\n" ); // phpcs:ignore + fwrite( $f, "{$insertion}\n" ); // phpcs:ignore + fwrite( $f, "/* END {$marker} */\n" ); // phpcs:ignore + } + + // Close file. + fclose( $f ); // phpcs:ignore + return true; + } + + return false; + } } -/** - * Remove old CSS. - * - * Removes CSS when the textarea is empty, but still retains surrounding styles. - * - * @param string $field_id The CSS option field ID. - * @return bool True on write success, false on failure. - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_remove_old_css' ) ) { - function ot_remove_old_css( $field_id = '' ) { - - /* missing $field_id string */ - if ( '' == $field_id ) - return false; - - /* path to the dynamic.css file */ - $filepath = get_stylesheet_directory() . '/dynamic.css'; - - /* allow filter on path */ - $filepath = apply_filters( 'css_option_file_path', $filepath, $field_id ); - - /* remove CSS from file */ - if ( is_writeable( $filepath ) ) { - - /* get each line in the file */ - $markerdata = explode( "\n", implode( '', file( $filepath ) ) ); - - /* can't write to the file return false */ - if ( ! $f = ot_file_open( $filepath, 'w' ) ) - return false; - - $searching = true; - - /* has array of lines */ - if ( ! empty( $markerdata ) ) { - - /* foreach line of code */ - foreach ( $markerdata as $n => $markerline ) { - - /* found begining of marker, set $searching to false */ - if ( $markerline == "/* BEGIN {$field_id} */" ) - $searching = false; - - /* $searching is true, keep rewrite each line of CSS */ - if ( $searching == true ) { - if ( $n + 1 < count( $markerdata ) ) - ot_file_write( $f, "{$markerline}\n" ); - else - ot_file_write( $f, "{$markerline}" ); - } - - /* found end marker delete old CSS */ - if ( $markerline == "/* END {$field_id} */" ) { - ot_file_write( $f, "" ); - $searching = true; - } - - } - - } - - /* close file */ - ot_file_close( $f ); - return true; - - } - - return false; - - } - + /** + * Remove old CSS. + * + * Removes CSS when the textarea is empty, but still retains surrounding styles. + * + * @param string $field_id The CSS option field ID. + * @return bool True on write success, false on failure. + * + * @access public + * @since 2.0 + */ + function ot_remove_old_css( $field_id = '' ) { + + // Missing $field_id string. + if ( '' === $field_id ) { + return false; + } + + // Path to the dynamic.css file. + $filepath = get_stylesheet_directory() . '/dynamic.css'; + + // Allow filter on path. + $filepath = apply_filters( 'css_option_file_path', $filepath, $field_id ); + + // Remove CSS from file, but ensure the file is actually CSS first. + if ( is_writeable( $filepath ) && 'css' === end( explode( '.', basename( $filepath ) ) ) ) { + + // Open the file. + $f = @fopen( $filepath, 'w' ); // phpcs:ignore + + // Can't write to the file return false. + if ( ! $f ) { + /* translators: %s: file path */ + $string = esc_html__( 'Unable to open the %s file in write mode.', 'option-tree' ); + add_settings_error( 'option-tree', 'dynamic_css', sprintf( $string, '' . $filepath . '' ), 'error' ); + return false; + } + + // Get each line in the file. + $markerdata = explode( "\n", implode( '', file( $filepath ) ) ); + + $searching = true; + + // Has array of lines. + if ( ! empty( $markerdata ) ) { + + // Foreach line of code. + foreach ( $markerdata as $n => $markerline ) { + + // Found beginning of marker, set $searching to false. + if ( "/* BEGIN {$field_id} */" === $markerline ) { + $searching = false; + } + + // Searching is true, keep writing each line of CSS. + if ( true === $searching ) { + if ( $n + 1 < count( $markerdata ) ) { + fwrite( $f, "{$markerline}\n" ); // phpcs:ignore + } else { + fwrite( $f, "{$markerline}" ); // phpcs:ignore + } + } + + // Found end marker delete old CSS. + if ( "/* END {$field_id} */" === $markerline ) { + fwrite( $f, '' ); // phpcs:ignore + $searching = true; + } + } + } + + // Close file. + fclose( $f ); // phpcs:ignore + return true; + } + + return false; + } } -/** - * Normalize CSS - * - * Normalize & Convert all line-endings to UNIX format. - * - * @param string $css - * @return string - * - * @access public - * @since 1.1.8 - * @updated 2.0 - */ if ( ! function_exists( 'ot_normalize_css' ) ) { - function ot_normalize_css( $css ) { - - /* Normalize & Convert */ - $css = str_replace( "\r\n", "\n", $css ); - $css = str_replace( "\r", "\n", $css ); - - /* Don't allow out-of-control blank lines */ - $css = preg_replace( "/\n{2,}/", "\n\n", $css ); - - return $css; - } - -} - -/** - * Helper function to loop over the option types. - * - * @param array $type The current option type. - * - * @return string - * - * @access public - * @since 2.0 - */ -if ( ! function_exists( 'ot_loop_through_option_types' ) ) { - - function ot_loop_through_option_types( $type = '', $child = false ) { - - $content = ''; - $types = ot_option_types_array(); - - if ( $child ) - unset($types['list-item']); - - foreach( $types as $key => $value ) - $content.= ''; - - return $content; - - } - + /** + * Normalize CSS + * + * Normalize & Convert all line-endings to UNIX format. + * + * @param string $css The CSS styles. + * + * @return string + * + * @access public + * @since 1.1.8 + * @updated 2.0 + */ + function ot_normalize_css( $css ) { + + // Normalize & Convert. + $css = str_replace( "\r\n", "\n", $css ); + $css = str_replace( "\r", "\n", $css ); + + // Don't allow out-of-control blank lines . + $css = preg_replace( "/\n{2,}/", "\n\n", $css ); + + return $css; + } } -/** - * Helper function to loop over choices. - * - * @param string $name The form element name. - * @param array $choices The array of choices. - * - * @return string - * - * @access public - * @since 2.0 - */ -if ( ! function_exists( 'ot_loop_through_choices' ) ) { - - function ot_loop_through_choices( $name, $choices = array() ) { - - $content = ''; - - foreach( (array) $choices as $key => $choice ) - $content.= '
  • ' . ot_choices_view( $name, $key, $choice ) . '
  • '; - - return $content; - } - +if ( ! function_exists( 'ot_loop_through_option_types' ) ) { + + /** + * Helper function to loop over the option types. + * + * @param string $type The current option type. + * @param bool $child Whether of not there are children elements. + * + * @return string + * + * @access public + * @since 2.0 + */ + function ot_loop_through_option_types( $type = '', $child = false ) { + + $content = ''; + $types = ot_option_types_array(); + + if ( $child ) { + unset( $types['list-item'] ); + } + + foreach ( $types as $key => $value ) { + $content .= ''; + } + + return $content; + + } } -/** - * Helper function to loop over sub settings. - * - * @param string $name The form element name. - * @param array $settings The array of settings. - * - * @return string - * - * @access public - * @since 2.0 - */ -if ( ! function_exists( 'ot_loop_through_sub_settings' ) ) { - - function ot_loop_through_sub_settings( $name, $settings = array() ) { - - $content = ''; - - foreach( $settings as $key => $setting ) - $content.= '
  • ' . ot_settings_view( $name, $key, $setting ) . '
  • '; - - return $content; - } - +if ( ! function_exists( 'ot_loop_through_choices' ) ) { + + /** + * Helper function to loop over choices. + * + * @param string $name The form element name. + * @param array $choices The array of choices. + * + * @return string + * + * @access public + * @since 2.0 + */ + function ot_loop_through_choices( $name, $choices = array() ) { + + $content = ''; + + foreach ( (array) $choices as $key => $choice ) { + if ( is_array( $choice ) ) { + $content .= '
  • ' . ot_choices_view( $name, $key, $choice ) . '
  • '; + } + } + + return $content; + } } -/** - * Helper function to display sections. - * - * This function is used in AJAX to add a new section - * and when section have already been added and saved. - * - * @param int $key The array key for the current element. - * @param array An array of values for the current section. - * - * @return void - * - * @access public - * @since 2.0 - */ +if ( ! function_exists( 'ot_loop_through_sub_settings' ) ) { + + /** + * Helper function to loop over sub settings. + * + * @param string $name The form element name. + * @param array $settings The array of settings. + * + * @return string + * + * @access public + * @since 2.0 + */ + function ot_loop_through_sub_settings( $name, $settings = array() ) { + + $content = ''; + + foreach ( $settings as $key => $setting ) { + if ( is_array( $setting ) ) { + $content .= '
  • ' . ot_settings_view( $name, $key, $setting ) . '
  • '; + } + } + + return $content; + } +} + if ( ! function_exists( 'ot_sections_view' ) ) { - function ot_sections_view( $name, $key, $section = array() ) { - - return ' -
    -
    ' . ( isset( $section['title'] ) ? esc_attr( $section['title'] ) : 'Section ' . ( $key + 1 ) ) . '
    -
    - - ' . __( 'Edit', 'option-tree' ) . ' - - - ' . __( 'Delete', 'option-tree' ) . ' - -
    -
    -
    -
    -
    ' . __( 'Section Title: Displayed as a menu item on the Theme Options page.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    -
    ' . __( 'Section ID: A unique lower case alphanumeric string, underscores allowed.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    '; - - } - + /** + * Helper function to display sections. + * + * This function is used in AJAX to add a new section + * and when section have already been added and saved. + * + * @param string $name The form element name. + * @param int $key The array key for the current element. + * @param array $section An array of values for the current section. + * + * @return string + * + * @access public + * @since 2.0 + */ + function ot_sections_view( $name, $key, $section = array() ) { + + /* translators: %s: Section Title emphasized */ + $str_title = esc_html__( '%s: Displayed as a menu item on the Theme Options page.', 'option-tree' ); + + /* translators: %s: Section ID emphasized */ + $str_id = esc_html__( '%s: A unique lower case alphanumeric string, underscores allowed.', 'option-tree' ); + + return ' +
    +
    ' . ( isset( $section['title'] ) ? esc_attr( $section['title'] ) : 'Section ' . ( absint( $key ) + 1 ) ) . '
    +
    + + ' . esc_html__( 'Edit', 'option-tree' ) . ' + + + ' . esc_html__( 'Delete', 'option-tree' ) . ' + +
    +
    +
    +
    +
    ' . sprintf( $str_title, '' . esc_html__( 'Section Title', 'option-tree' ) . '', 'option-tree' ) . '
    +
    + +
    +
    +
    +
    +
    +
    ' . sprintf( $str_id, '' . esc_html__( 'Section ID', 'option-tree' ) . '', 'option-tree' ) . '
    +
    + +
    +
    +
    +
    +
    '; + } } -/** - * Helper function to display settings. - * - * This function is used in AJAX to add a new setting - * and when settings have already been added and saved. - * - * @param int $key The array key for the current element. - * @param array An array of values for the current section. - * - * @return void - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_settings_view' ) ) { - function ot_settings_view( $name, $key, $setting = array() ) { - - $child = ( strpos( $name, '][settings]') !== false ) ? true : false; - $type = isset( $setting['type'] ) ? $setting['type'] : ''; - $std = isset( $setting['std'] ) ? $setting['std'] : ''; - $operator = isset( $setting['operator'] ) ? esc_attr( $setting['operator'] ) : 'and'; - - // Serialize the standard value just incase - if ( is_array( $std ) ) { - $std = maybe_serialize( $std ); - } - - if ( in_array( $type, array( 'css', 'javascript', 'textarea', 'textarea-simple' ) ) ) { - $std_form_element = ''; - } else { - $std_form_element = ''; - } - - return ' -
    -
    ' . ( isset( $setting['label'] ) ? esc_attr( $setting['label'] ) : 'Setting ' . ( $key + 1 ) ) . '
    -
    - - ' . __( 'Edit', 'option-tree' ) . ' - - - ' . __( 'Delete', 'option-tree' ) . ' - -
    -
    -
    -
    -
    ' . __( 'Label: Displayed as the label of a form element on the Theme Options page.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    -
    ' . __( 'ID: A unique lower case alphanumeric string, underscores allowed.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    -
    ' . __( 'Type: Choose one of the available option types from the dropdown.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    -
    ' . __( 'Description: Enter a detailed description for the users to read on the Theme Options page, HTML is allowed. This is also where you enter content for both the Textblock & Textblock Titled option types.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    -
    ' . __( 'Choices: This will only affect the following option types: Checkbox, Radio, Select & Select Image.', 'option-tree' ) . '
    -
    -
      - ' . ( isset( $setting['choices'] ) ? ot_loop_through_choices( $name . '[' . $key . ']', $setting['choices'] ) : '' ) . ' -
    - ' . __( 'Add Choice', 'option-tree' ) . ' -
    -
    -
    -
    -
    -
    ' . __( 'Settings: This will only affect the List Item option type.', 'option-tree' ) . '
    -
    -
      - ' . ( isset( $setting['settings'] ) ? ot_loop_through_sub_settings( $name . '[' . $key . '][settings]', $setting['settings'] ) : '' ) . ' -
    - ' . __( 'Add Setting', 'option-tree' ) . ' -
    -
    -
    -
    -
    -
    ' . __( 'Standard: Setting the standard value for your option only works for some option types. Read the OptionTree->Documentation for more information on which ones.', 'option-tree' ) . '
    -
    - ' . $std_form_element . ' -
    -
    -
    -
    -
    -
    ' . __( 'Rows: Enter a numeric value for the number of rows in your textarea. This will only affect the following option types: CSS, Textarea, & Textarea Simple.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    -
    ' . __( 'Post Type: Add a comma separated list of post type like \'post,page\'. This will only affect the following option types: Custom Post Type Checkbox, & Custom Post Type Select.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    -
    ' . __( 'Taxonomy: Add a comma separated list of any registered taxonomy like \'category,post_tag\'. This will only affect the following option types: Taxonomy Checkbox, & Taxonomy Select.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    -
    ' . __( 'Min, Max, & Step: Add a comma separated list of options in the following format 0,100,1 (slide from 0-100 in intervals of 1). The three values represent the minimum, maximum, and step options and will only affect the Numeric Slider option type.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    -
    ' . __( 'CSS Class: Add and optional class to this option type.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    -
    ' . sprintf( __( 'Condition: Add a comma separated list (no spaces) of conditions in which the field will be visible, leave this setting empty to always show the field. In these examples, value is a placeholder for your condition, which can be in the form of %s.', 'option-tree' ), 'field_id:is(value), field_id:not(value), field_id:contains(value), field_id:less_than(value), field_id:less_than_or_equal_to(value), field_id:greater_than(value), or field_id:greater_than_or_equal_to(value)' ) . '
    -
    - -
    -
    -
    -
    -
    -
    ' . __( 'Operator: Choose the logical operator to compute the result of the conditions.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    - ' . ( ! $child ? '' : '' ); - - } - + /** + * Helper function to display settings. + * + * This function is used in AJAX to add a new setting + * and when settings have already been added and saved. + * + * @param string $name The form element name. + * @param int $key The array key for the current element. + * @param array $setting An array of values for the current setting. + * + * @return string + * + * @access public + * @since 2.0 + */ + function ot_settings_view( $name, $key, $setting = array() ) { + + $child = ( false !== strpos( $name, '][settings]' ) ) ? true : false; + $type = isset( $setting['type'] ) ? $setting['type'] : ''; + $std = isset( $setting['std'] ) ? $setting['std'] : ''; + $operator = isset( $setting['operator'] ) ? esc_attr( $setting['operator'] ) : 'and'; + + // Serialize the standard value just in case. + if ( is_array( $std ) ) { + $std = maybe_serialize( $std ); + } + + if ( in_array( $type, array( 'css', 'javascript', 'textarea', 'textarea-simple' ), true ) ) { + $std_form_element = ''; + } else { + $std_form_element = ''; + } + + /* translators: %s: Label emphasized */ + $str_label = esc_html__( '%s: Displayed as the label of a form element on the Theme Options page.', 'option-tree' ); + + /* translators: %s: ID emphasized */ + $str_id = esc_html__( '%s: A unique lower case alphanumeric string, underscores allowed.', 'option-tree' ); + + /* translators: %s: Type emphasized */ + $str_type = esc_html__( '%s: Choose one of the available option types from the dropdown.', 'option-tree' ); + + /* translators: %s: Description emphasized */ + $str_desc = esc_html__( '%s: Enter a detailed description for the users to read on the Theme Options page, HTML is allowed. This is also where you enter content for both the Textblock & Textblock Titled option types.', 'option-tree' ); + + /* translators: %s: Choices emphasized */ + $str_choices = esc_html__( '%s: This will only affect the following option types: Checkbox, Radio, Select & Select Image.', 'option-tree' ); + + /* translators: %s: Settings emphasized */ + $str_settings = esc_html__( '%s: This will only affect the List Item option type.', 'option-tree' ); + + /* translators: %1$s: Standard emphasized, %2$s: visual path to documentation */ + $str_standard = esc_html__( '%1$s: Setting the standard value for your option only works for some option types. Read the %2$s for more information on which ones.', 'option-tree' ); + + /* translators: %s: Rows emphasized */ + $str_rows = esc_html__( '%s: Enter a numeric value for the number of rows in your textarea. This will only affect the following option types: CSS, Textarea, & Textarea Simple.', 'option-tree' ); + + /* translators: %s: Post Type emphasized */ + $str_post_type = esc_html__( '%s: Add a comma separated list of post type like \'post,page\'. This will only affect the following option types: Custom Post Type Checkbox, & Custom Post Type Select.', 'option-tree' ); + + /* translators: %s: Taxonomy emphasized */ + $str_taxonomy = esc_html__( '%s: Add a comma separated list of any registered taxonomy like \'category,post_tag\'. This will only affect the following option types: Taxonomy Checkbox, & Taxonomy Select.', 'option-tree' ); + + /* translators: %1$s: Min, Max, & Step emphasized, %2$s: format, %3$s: range, %4$s: minimum interval */ + $str_min_max_step = esc_html__( '%1$s: Add a comma separated list of options in the following format %2$s (slide from %3$s in intervals of %4$s). The three values represent the minimum, maximum, and step options and will only affect the Numeric Slider option type.', 'option-tree' ); + + /* translators: %s: CSS Class emphasized */ + $str_css_class = esc_html__( '%s: Add and optional class to this option type.', 'option-tree' ); + + /* translators: %1$s: Condition emphasized, %2$s: example value, %3$s: list of valid conditions */ + $str_condition = esc_html__( '%1$s: Add a comma separated list (no spaces) of conditions in which the field will be visible, leave this setting empty to always show the field. In these examples, %2$s is a placeholder for your condition, which can be in the form of %3$s.', 'option-tree' ); + + /* translators: %s: Operator emphasized */ + $str_operator = esc_html__( '%s: Choose the logical operator to compute the result of the conditions.', 'option-tree' ); + + return ' +
    +
    ' . ( isset( $setting['label'] ) ? esc_attr( $setting['label'] ) : 'Setting ' . ( absint( $key ) + 1 ) ) . '
    +
    + + ' . esc_html__( 'Edit', 'option-tree' ) . ' + + + ' . esc_html__( 'Delete', 'option-tree' ) . ' + +
    +
    +
    +
    +
    ' . sprintf( $str_label, '' . esc_html__( 'Label', 'option-tree' ) . '' ) . '
    +
    + +
    +
    +
    +
    +
    +
    ' . sprintf( $str_id, '' . esc_html__( 'ID', 'option-tree' ) . '' ) . '
    +
    + +
    +
    +
    +
    +
    +
    ' . sprintf( $str_type, '' . esc_html__( 'Type', 'option-tree' ) . '' ) . '
    +
    + +
    +
    +
    +
    +
    +
    ' . sprintf( $str_desc, '' . esc_html__( 'Description', 'option-tree' ) . '' ) . '
    +
    + +
    +
    +
    +
    +
    +
    ' . sprintf( $str_choices, '' . esc_html__( 'Choices', 'option-tree' ) . '' ) . '
    +
    +
      + ' . ( isset( $setting['choices'] ) ? ot_loop_through_choices( $name . '[' . $key . ']', $setting['choices'] ) : '' ) . ' +
    + ' . esc_html__( 'Add Choice', 'option-tree' ) . ' +
    +
    +
    +
    +
    +
    ' . sprintf( $str_settings, '' . esc_html__( 'Settings', 'option-tree' ) . '' ) . '
    +
    +
      + ' . ( isset( $setting['settings'] ) ? ot_loop_through_sub_settings( $name . '[' . $key . '][settings]', $setting['settings'] ) : '' ) . ' +
    + ' . esc_html__( 'Add Setting', 'option-tree' ) . ' +
    +
    +
    +
    +
    +
    ' . sprintf( $str_standard, '' . esc_html__( 'Standard', 'option-tree' ) . '', '' . esc_html__( 'OptionTree->Documentation', 'option-tree' ) . '' ) . '
    +
    + ' . $std_form_element . ' +
    +
    +
    +
    +
    +
    ' . sprintf( $str_rows, '' . esc_html__( 'Rows', 'option-tree' ) . '' ) . '
    +
    + +
    +
    +
    +
    +
    +
    ' . sprintf( $str_post_type, '' . esc_html__( 'Post Type', 'option-tree' ) . '' ) . '
    +
    + +
    +
    +
    +
    +
    +
    ' . sprintf( $str_taxonomy, '' . esc_html__( 'Taxonomy', 'option-tree' ) . '' ) . '
    +
    + +
    +
    +
    +
    +
    +
    ' . sprintf( $str_min_max_step, '' . esc_html__( 'Min, Max, & Step', 'option-tree' ) . '', '0,100,1', '0-100', '1' ) . '
    +
    + +
    +
    +
    +
    +
    +
    ' . sprintf( $str_css_class, '' . esc_html__( 'CSS Class', 'option-tree' ) . '' ) . '
    +
    + +
    +
    +
    +
    +
    +
    ' . sprintf( $str_condition, '' . esc_html__( 'Condition', 'option-tree' ) . '', 'value', 'field_id:is(value), field_id:not(value), field_id:contains(value), field_id:less_than(value), field_id:less_than_or_equal_to(value), field_id:greater_than(value), or field_id:greater_than_or_equal_to(value)' ) . '
    +
    + +
    +
    +
    +
    +
    +
    ' . sprintf( $str_operator, '' . esc_html__( 'Operator', 'option-tree' ) . '' ) . '
    +
    + +
    +
    +
    +
    +
    + ' . ( ! $child ? '' : '' ); + } } -/** - * Helper function to display setting choices. - * - * This function is used in AJAX to add a new choice - * and when choices have already been added and saved. - * - * @param string $name The form element name. - * @param array $key The array key for the current element. - * @param array An array of values for the current choice. - * - * @return void - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_choices_view' ) ) { - function ot_choices_view( $name, $key, $choice = array() ) { - - return ' -
    -
    ' . ( isset( $choice['label'] ) ? esc_attr( $choice['label'] ) : 'Choice ' . ( $key + 1 ) ) . '
    -
    - - ' . __( 'Edit', 'option-tree' ) . ' - - - ' . __( 'Delete', 'option-tree' ) . ' - -
    -
    -
    -
    -
    ' . __( 'Label', 'option-tree' ) . '
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    ' . __( 'Value', 'option-tree' ) . '
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    ' . __( 'Image Source (Radio Image only)', 'option-tree' ) . '
    -
    -
    -
    - -
    -
    -
    -
    '; - - } - + /** + * Helper function to display setting choices. + * + * This function is used in AJAX to add a new choice + * and when choices have already been added and saved. + * + * @param string $name The form element name. + * @param int $key The array key for the current element. + * @param array $choice An array of values for the current choice. + * + * @return string + * + * @access public + * @since 2.0 + */ + function ot_choices_view( $name, $key, $choice = array() ) { + + return ' +
    +
    ' . ( isset( $choice['label'] ) ? esc_attr( $choice['label'] ) : 'Choice ' . ( absint( $key ) + 1 ) ) . '
    + +
    +
    +
    +
    ' . esc_html__( 'Label', 'option-tree' ) . '
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    ' . esc_html__( 'Value', 'option-tree' ) . '
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    ' . esc_html__( 'Image Source (Radio Image only)', 'option-tree' ) . '
    +
    +
    +
    + +
    +
    +
    +
    +
    '; + + } } -/** - * Helper function to display sections. - * - * This function is used in AJAX to add a new section - * and when section have already been added and saved. - * - * @param int $key The array key for the current element. - * @param array An array of values for the current section. - * - * @return void - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_contextual_help_view' ) ) { - function ot_contextual_help_view( $name, $key, $content = array() ) { - - return ' -
    -
    ' . ( isset( $content['title'] ) ? esc_attr( $content['title'] ) : 'Content ' . ( $key + 1 ) ) . '
    - -
    -
    -
    -
    ' . __( 'Title: Displayed as a contextual help menu item on the Theme Options page.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    -
    ' . __( 'ID: A unique lower case alphanumeric string, underscores allowed.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    -
    ' . __( 'Content: Enter the HTML content about this contextual help item displayed on the Theme Option page for end users to read.', 'option-tree' ) . '
    -
    - -
    -
    -
    -
    -
    '; - - } - + /** + * Helper function to display sections. + * + * This function is used in AJAX to add a new section + * and when section have already been added and saved. + * + * @param string $name The name/ID of the help page. + * @param int $key The array key for the current element. + * @param array $content An array of values for the current section. + * + * @return string + * + * @access public + * @since 2.0 + */ + function ot_contextual_help_view( $name, $key, $content = array() ) { + + /* translators: %s: Title emphasized */ + $str_title = esc_html__( '%s: Displayed as a contextual help menu item on the Theme Options page.', 'option-tree' ); + + /* translators: %s: ID emphasized */ + $str_id = esc_html__( '%s: A unique lower case alphanumeric string, underscores allowed.', 'option-tree' ); + + /* translators: %s: Content emphasized */ + $str_content = esc_html__( '%s: Enter the HTML content about this contextual help item displayed on the Theme Option page for end users to read.', 'option-tree' ); + + return ' +
    +
    ' . ( isset( $content['title'] ) ? esc_attr( $content['title'] ) : 'Content ' . ( absint( $key ) + 1 ) ) . '
    + +
    +
    +
    +
    ' . sprintf( $str_title, '' . esc_html__( 'Title', 'option-tree' ) . '' ) . '
    +
    + +
    +
    +
    +
    +
    +
    ' . sprintf( $str_id, '' . esc_html__( 'ID', 'option-tree' ) . '' ) . '
    +
    + +
    +
    +
    +
    +
    +
    ' . sprintf( $str_content, '' . esc_html__( 'Content', 'option-tree' ) . '' ) . '
    +
    + +
    +
    +
    +
    +
    '; + + } } -/** - * Helper function to display sections. - * - * @param string $key - * @param string $data - * @param string $active_layout - * - * @return void - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_layout_view' ) ) { - function ot_layout_view( $key, $data = '', $active_layout = '' ) { - - return ' -
    -
    ' . ( isset( $key ) ? esc_attr( $key ) : __( 'Layout', 'option-tree' ) ) . '
    - - -
    '; - - } - + /** + * Helper function to display sections. + * + * @param string $key Layout ID. + * @param string $data Layout encoded value. + * @param string $active_layout Active layout ID. + * + * @return string + * + * @access public + * @since 2.0 + */ + function ot_layout_view( $key, $data = '', $active_layout = '' ) { + + return ' +
    +
    ' . ( isset( $key ) ? esc_attr( $key ) : esc_html__( 'Layout', 'option-tree' ) ) . '
    + + +
    '; + } } -/** - * Helper function to display list items. - * - * This function is used in AJAX to add a new list items - * and when they have already been added and saved. - * - * @param string $name The form field name. - * @param int $key The array key for the current element. - * @param array An array of values for the current list item. - * - * @return void - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_list_item_view' ) ) { - function ot_list_item_view( $name, $key, $list_item = array(), $post_id = 0, $get_option = '', $settings = array(), $type = '' ) { - - /* required title setting */ - $required_setting = array( - array( - 'id' => 'title', - 'label' => __( 'Title', 'option-tree' ), - 'desc' => '', - 'std' => '', - 'type' => 'text', - 'rows' => '', - 'class' => 'option-tree-setting-title', - 'post_type' => '', - 'choices' => array() - ) - ); - - /* load the old filterable slider settings */ - if ( 'slider' == $type ) { - - $settings = ot_slider_settings( $name ); - - } - - /* if no settings array load the filterable list item settings */ - if ( empty( $settings ) ) { - - $settings = ot_list_item_settings( $name ); - - } - - /* merge the two settings array */ - $settings = array_merge( $required_setting, $settings ); - - echo ' -
    -
    ' . ( isset( $list_item['title'] ) ? esc_attr( $list_item['title'] ) : '' ) . '
    - -
    '; - - foreach( $settings as $field ) { - - // Set field value - $field_value = isset( $list_item[$field['id']] ) ? $list_item[$field['id']] : ''; - - /* set default to standard value */ - if ( isset( $field['std'] ) ) { - $field_value = ot_filter_std_value( $field_value, $field['std'] ); - } - - // filter the title label and description - if ( $field['id'] == 'title' ) { - - // filter the label - $field['label'] = apply_filters( 'ot_list_item_title_label', $field['label'], $name ); - - // filter the description - $field['desc'] = apply_filters( 'ot_list_item_title_desc', $field['desc'], $name ); - - } - - /* make life easier */ - $_field_name = $get_option ? $get_option . '[' . $name . ']' : $name; - - /* build the arguments array */ - $_args = array( - 'type' => $field['type'], - 'field_id' => $name . '_' . $field['id'] . '_' . $key, - 'field_name' => $_field_name . '[' . $key . '][' . $field['id'] . ']', - 'field_value' => $field_value, - 'field_desc' => isset( $field['desc'] ) ? $field['desc'] : '', - 'field_std' => isset( $field['std'] ) ? $field['std'] : '', - 'field_rows' => isset( $field['rows'] ) ? $field['rows'] : 10, - 'field_post_type' => isset( $field['post_type'] ) && ! empty( $field['post_type'] ) ? $field['post_type'] : 'post', - 'field_taxonomy' => isset( $field['taxonomy'] ) && ! empty( $field['taxonomy'] ) ? $field['taxonomy'] : 'category', - 'field_min_max_step'=> isset( $field['min_max_step'] ) && ! empty( $field['min_max_step'] ) ? $field['min_max_step'] : '0,100,1', - 'field_class' => isset( $field['class'] ) ? $field['class'] : '', - 'field_condition' => isset( $field['condition'] ) ? $field['condition'] : '', - 'field_operator' => isset( $field['operator'] ) ? $field['operator'] : 'and', - 'field_choices' => isset( $field['choices'] ) && ! empty( $field['choices'] ) ? $field['choices'] : array(), - 'field_settings' => isset( $field['settings'] ) && ! empty( $field['settings'] ) ? $field['settings'] : array(), - 'post_id' => $post_id, - 'get_option' => $get_option - ); - - $conditions = ''; - - /* setup the conditions */ - if ( isset( $field['condition'] ) && ! empty( $field['condition'] ) ) { - - /* doing magic on the conditions so they work in a list item */ - $conditionals = explode( ',', $field['condition'] ); - foreach( $conditionals as $condition ) { - $parts = explode( ':', $condition ); - if ( isset( $parts[0] ) ) { - $field['condition'] = str_replace( $condition, $name . '_' . $parts[0] . '_' . $key . ':' . $parts[1], $field['condition'] ); - } - } - - $conditions = ' data-condition="' . $field['condition'] . '"'; - $conditions.= isset( $field['operator'] ) && in_array( $field['operator'], array( 'and', 'AND', 'or', 'OR' ) ) ? ' data-operator="' . $field['operator'] . '"' : ''; - - } - - // Build the setting CSS class - if ( ! empty( $_args['field_class'] ) ) { - - $classes = explode( ' ', $_args['field_class'] ); - - foreach( $classes as $_key => $value ) { - - $classes[$_key] = $value . '-wrap'; - - } - - $class = 'format-settings ' . implode( ' ', $classes ); - - } else { - - $class = 'format-settings'; - - } - - /* option label */ - echo '
    '; - - /* don't show title with textblocks */ - if ( $_args['type'] != 'textblock' && ! empty( $field['label'] ) ) { - echo '
    '; - echo '

    ' . esc_attr( $field['label'] ) . '

    '; - echo '
    '; - } - - /* only allow simple textarea inside a list-item due to known DOM issues with wp_editor() */ - if ( apply_filters( 'ot_override_forced_textarea_simple', false, $field['id'] ) == false && $_args['type'] == 'textarea' ) - $_args['type'] = 'textarea-simple'; - - /* option body, list-item is not allowed inside another list-item */ - if ( $_args['type'] !== 'list-item' && $_args['type'] !== 'slider' ) { - echo ot_display_by_type( $_args ); - } - - echo '
    '; - - } - - echo '
    '; - - echo '
    '; - - } - + /** + * Helper function to display list items. + * + * This function is used in AJAX to add a new list items + * and when they have already been added and saved. + * + * @param string $name The form field name. + * @param int $key The array key for the current element. + * @param array $list_item An array of values for the current list item. + * @param int $post_id The post ID. + * @param string $get_option The option page ID. + * @param array $settings The settings. + * @param string $type The list type. + * + * @access public + * @since 2.0 + */ + function ot_list_item_view( $name, $key, $list_item = array(), $post_id = 0, $get_option = '', $settings = array(), $type = '' ) { + + // Required title setting. + $required_setting = array( + array( + 'id' => 'title', + 'label' => __( 'Title', 'option-tree' ), + 'desc' => '', + 'std' => '', + 'type' => 'text', + 'rows' => '', + 'class' => 'option-tree-setting-title', + 'post_type' => '', + 'choices' => array(), + ), + ); + + // Load the old filterable slider settings. + if ( 'slider' === $type ) { + $settings = ot_slider_settings( $name ); + } + + // If no settings array load the filterable list item settings. + if ( empty( $settings ) ) { + $settings = ot_list_item_settings( $name ); + } + + // Merge the two settings array. + $settings = array_merge( $required_setting, $settings ); + + echo ' +
    +
    ' . ( isset( $list_item['title'] ) ? esc_attr( $list_item['title'] ) : '' ) . '
    + +
    + '; + + foreach ( $settings as $field ) { + + // Set field value. + $field_value = isset( $list_item[ $field['id'] ] ) ? $list_item[ $field['id'] ] : ''; + + // Set default to standard value. + if ( isset( $field['std'] ) ) { + $field_value = ot_filter_std_value( $field_value, $field['std'] ); + } + + // filter the title label and description. + if ( 'title' === $field['id'] ) { + + // filter the label. + $field['label'] = apply_filters( 'ot_list_item_title_label', $field['label'], $name ); + + // filter the description. + $field['desc'] = apply_filters( 'ot_list_item_title_desc', $field['desc'], $name ); + } + + // Make life easier. + $_field_name = $get_option ? $get_option . '[' . $name . ']' : $name; + + // Build the arguments array. + $_args = array( + 'type' => $field['type'], + 'field_id' => $name . '_' . $field['id'] . '_' . $key, + 'field_name' => $_field_name . '[' . $key . '][' . $field['id'] . ']', + 'field_value' => $field_value, + 'field_desc' => isset( $field['desc'] ) ? $field['desc'] : '', + 'field_std' => isset( $field['std'] ) ? $field['std'] : '', + 'field_rows' => isset( $field['rows'] ) ? $field['rows'] : 10, + 'field_post_type' => isset( $field['post_type'] ) && ! empty( $field['post_type'] ) ? $field['post_type'] : 'post', + 'field_taxonomy' => isset( $field['taxonomy'] ) && ! empty( $field['taxonomy'] ) ? $field['taxonomy'] : 'category', + 'field_min_max_step' => isset( $field['min_max_step'] ) && ! empty( $field['min_max_step'] ) ? $field['min_max_step'] : '0,100,1', + 'field_class' => isset( $field['class'] ) ? $field['class'] : '', + 'field_condition' => isset( $field['condition'] ) ? $field['condition'] : '', + 'field_operator' => isset( $field['operator'] ) ? $field['operator'] : 'and', + 'field_choices' => isset( $field['choices'] ) && ! empty( $field['choices'] ) ? $field['choices'] : array(), + 'field_settings' => isset( $field['settings'] ) && ! empty( $field['settings'] ) ? $field['settings'] : array(), + 'post_id' => $post_id, + 'get_option' => $get_option, + ); + + $conditions = ''; + + // Setup the conditions. + if ( isset( $field['condition'] ) && ! empty( $field['condition'] ) ) { + + /* doing magic on the conditions so they work in a list item */ + $conditionals = explode( ',', $field['condition'] ); + foreach ( $conditionals as $condition ) { + $parts = explode( ':', $condition ); + if ( isset( $parts[0] ) ) { + $field['condition'] = str_replace( $condition, $name . '_' . $parts[0] . '_' . $key . ':' . $parts[1], $field['condition'] ); + } + } + + $conditions = ' data-condition="' . esc_attr( $field['condition'] ) . '"'; + $conditions .= isset( $field['operator'] ) && in_array( $field['operator'], array( 'and', 'AND', 'or', 'OR' ), true ) ? ' data-operator="' . esc_attr( $field['operator'] ) . '"' : ''; + } + + // Build the setting CSS class. + if ( ! empty( $_args['field_class'] ) ) { + $classes = explode( ' ', $_args['field_class'] ); + + foreach ( $classes as $_key => $value ) { + $classes[ $_key ] = $value . '-wrap'; + } + + $class = 'format-settings ' . implode( ' ', $classes ); + } else { + $class = 'format-settings'; + } + + // Option label. + echo '
    '; // phpcs:ignore + + // Don't show title with textblocks. + if ( 'textblock' !== $_args['type'] && ! empty( $field['label'] ) ) { + echo '
    '; + echo '

    ' . esc_attr( $field['label'] ) . '

    '; + echo '
    '; + } + + // Only allow simple textarea inside a list-item due to known DOM issues with wp_editor(). + if ( false === apply_filters( 'ot_override_forced_textarea_simple', false, $field['id'] ) && 'textarea' === $_args['type'] ) { + $_args['type'] = 'textarea-simple'; + } + + // Option body, list-item is not allowed inside another list-item. + if ( 'list-item' !== $_args['type'] && 'slider' !== $_args['type'] ) { + echo ot_display_by_type( $_args ); // phpcs:ignore + } + + echo '
    '; + } + + echo '
    '; + + echo '
    '; + } } -/** - * Helper function to display social links. - * - * This function is used in AJAX to add a new list items - * and when they have already been added and saved. - * - * @param string $name The form field name. - * @param int $key The array key for the current element. - * @param array An array of values for the current list item. - * - * @return void - * - * @access public - * @since 2.4.0 - */ if ( ! function_exists( 'ot_social_links_view' ) ) { - function ot_social_links_view( $name, $key, $list_item = array(), $post_id = 0, $get_option = '', $settings = array(), $type = '' ) { - - /* if no settings array load the filterable social links settings */ - if ( empty( $settings ) ) { - - $settings = ot_social_links_settings( $name ); - - } - - echo ' -
    -
    ' . ( isset( $list_item['name'] ) ? esc_attr( $list_item['name'] ) : '' ) . '
    - -
    '; - - foreach( $settings as $field ) { - - // Set field value - $field_value = isset( $list_item[$field['id']] ) ? $list_item[$field['id']] : ''; - - /* set default to standard value */ - if ( isset( $field['std'] ) ) { - $field_value = ot_filter_std_value( $field_value, $field['std'] ); - } - - /* make life easier */ - $_field_name = $get_option ? $get_option . '[' . $name . ']' : $name; - - /* build the arguments array */ - $_args = array( - 'type' => $field['type'], - 'field_id' => $name . '_' . $field['id'] . '_' . $key, - 'field_name' => $_field_name . '[' . $key . '][' . $field['id'] . ']', - 'field_value' => $field_value, - 'field_desc' => isset( $field['desc'] ) ? $field['desc'] : '', - 'field_std' => isset( $field['std'] ) ? $field['std'] : '', - 'field_rows' => isset( $field['rows'] ) ? $field['rows'] : 10, - 'field_post_type' => isset( $field['post_type'] ) && ! empty( $field['post_type'] ) ? $field['post_type'] : 'post', - 'field_taxonomy' => isset( $field['taxonomy'] ) && ! empty( $field['taxonomy'] ) ? $field['taxonomy'] : 'category', - 'field_min_max_step'=> isset( $field['min_max_step'] ) && ! empty( $field['min_max_step'] ) ? $field['min_max_step'] : '0,100,1', - 'field_class' => isset( $field['class'] ) ? $field['class'] : '', - 'field_condition' => isset( $field['condition'] ) ? $field['condition'] : '', - 'field_operator' => isset( $field['operator'] ) ? $field['operator'] : 'and', - 'field_choices' => isset( $field['choices'] ) && ! empty( $field['choices'] ) ? $field['choices'] : array(), - 'field_settings' => isset( $field['settings'] ) && ! empty( $field['settings'] ) ? $field['settings'] : array(), - 'post_id' => $post_id, - 'get_option' => $get_option - ); - - $conditions = ''; - - /* setup the conditions */ - if ( isset( $field['condition'] ) && ! empty( $field['condition'] ) ) { - - /* doing magic on the conditions so they work in a list item */ - $conditionals = explode( ',', $field['condition'] ); - foreach( $conditionals as $condition ) { - $parts = explode( ':', $condition ); - if ( isset( $parts[0] ) ) { - $field['condition'] = str_replace( $condition, $name . '_' . $parts[0] . '_' . $key . ':' . $parts[1], $field['condition'] ); - } - } - - $conditions = ' data-condition="' . $field['condition'] . '"'; - $conditions.= isset( $field['operator'] ) && in_array( $field['operator'], array( 'and', 'AND', 'or', 'OR' ) ) ? ' data-operator="' . $field['operator'] . '"' : ''; - - } - - /* option label */ - echo '
    '; - - /* don't show title with textblocks */ - if ( $_args['type'] != 'textblock' && ! empty( $field['label'] ) ) { - echo '
    '; - echo '

    ' . esc_attr( $field['label'] ) . '

    '; - echo '
    '; - } - - /* only allow simple textarea inside a list-item due to known DOM issues with wp_editor() */ - if ( $_args['type'] == 'textarea' ) - $_args['type'] = 'textarea-simple'; - - /* option body, list-item is not allowed inside another list-item */ - if ( $_args['type'] !== 'list-item' && $_args['type'] !== 'slider' && $_args['type'] !== 'social-links' ) { - echo ot_display_by_type( $_args ); - } - - echo '
    '; - - } - - echo '
    '; - - echo '
    '; - - } - + /** + * Helper function to display social links. + * + * This function is used in AJAX to add a new list items + * and when they have already been added and saved. + * + * @param string $name The form field name. + * @param int $key The array key for the current element. + * @param array $list_item An array of values for the current list item. + * @param int $post_id The post ID. + * @param string $get_option The option page ID. + * @param array $settings The settings. + * + * @access public + * @since 2.4.0 + */ + function ot_social_links_view( $name, $key, $list_item = array(), $post_id = 0, $get_option = '', $settings = array() ) { + + // If no settings array load the filterable social links settings. + if ( empty( $settings ) ) { + $settings = ot_social_links_settings( $name ); + } + + echo ' +
    +
    ' . ( isset( $list_item['name'] ) ? esc_attr( $list_item['name'] ) : '' ) . '
    + +
    + '; + + foreach ( $settings as $field ) { + + // Set field value. + $field_value = isset( $list_item[ $field['id'] ] ) ? $list_item[ $field['id'] ] : ''; + + // Set default to standard value. + if ( isset( $field['std'] ) ) { + $field_value = ot_filter_std_value( $field_value, $field['std'] ); + } + + // Make life easier. + $_field_name = $get_option ? $get_option . '[' . $name . ']' : $name; + + // Build the arguments array. + $_args = array( + 'type' => $field['type'], + 'field_id' => $name . '_' . $field['id'] . '_' . $key, + 'field_name' => $_field_name . '[' . $key . '][' . $field['id'] . ']', + 'field_value' => $field_value, + 'field_desc' => isset( $field['desc'] ) ? $field['desc'] : '', + 'field_std' => isset( $field['std'] ) ? $field['std'] : '', + 'field_rows' => isset( $field['rows'] ) ? $field['rows'] : 10, + 'field_post_type' => isset( $field['post_type'] ) && ! empty( $field['post_type'] ) ? $field['post_type'] : 'post', + 'field_taxonomy' => isset( $field['taxonomy'] ) && ! empty( $field['taxonomy'] ) ? $field['taxonomy'] : 'category', + 'field_min_max_step' => isset( $field['min_max_step'] ) && ! empty( $field['min_max_step'] ) ? $field['min_max_step'] : '0,100,1', + 'field_class' => isset( $field['class'] ) ? $field['class'] : '', + 'field_condition' => isset( $field['condition'] ) ? $field['condition'] : '', + 'field_operator' => isset( $field['operator'] ) ? $field['operator'] : 'and', + 'field_choices' => isset( $field['choices'] ) && ! empty( $field['choices'] ) ? $field['choices'] : array(), + 'field_settings' => isset( $field['settings'] ) && ! empty( $field['settings'] ) ? $field['settings'] : array(), + 'post_id' => $post_id, + 'get_option' => $get_option, + ); + + $conditions = ''; + + // Setup the conditions. + if ( isset( $field['condition'] ) && ! empty( $field['condition'] ) ) { + + // Doing magic on the conditions so they work in a list item. + $conditionals = explode( ',', $field['condition'] ); + foreach ( $conditionals as $condition ) { + $parts = explode( ':', $condition ); + if ( isset( $parts[0] ) ) { + $field['condition'] = str_replace( $condition, $name . '_' . $parts[0] . '_' . $key . ':' . $parts[1], $field['condition'] ); + } + } + + $conditions = ' data-condition="' . esc_attr( $field['condition'] ) . '"'; + $conditions .= isset( $field['operator'] ) && in_array( $field['operator'], array( 'and', 'AND', 'or', 'OR' ), true ) ? ' data-operator="' . esc_attr( $field['operator'] ) . '"' : ''; + } + + // Option label. + echo '
    '; // phpcs:ignore + + // Don't show title with textblocks. + if ( 'textblock' !== $_args['type'] && ! empty( $field['label'] ) ) { + echo '
    '; + echo '

    ' . esc_attr( $field['label'] ) . '

    '; + echo '
    '; + } + + // Only allow simple textarea inside a list-item due to known DOM issues with wp_editor(). + if ( 'textarea' === $_args['type'] ) { + $_args['type'] = 'textarea-simple'; + } + + // Option body, list-item is not allowed inside another list-item. + if ( 'list-item' !== $_args['type'] && 'slider' !== $_args['type'] && 'social-links' !== $_args['type'] ) { + echo ot_display_by_type( $_args ); // phpcs:ignore + } + + echo '
    '; + } + + echo '
    '; + + echo '
    '; + } } -/** - * Helper function to display Theme Options layouts form. - * - * @return string - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_theme_options_layouts_form' ) ) { - function ot_theme_options_layouts_form( $active = false ) { - - echo '
    '; - - /* form nonce */ - wp_nonce_field( 'option_tree_modify_layouts_form', 'option_tree_modify_layouts_nonce' ); - - /* get the saved layouts */ - $layouts = get_option( ot_layouts_id() ); - - /* set active layout */ - $active_layout = isset( $layouts['active_layout'] ) ? $layouts['active_layout'] : ''; - - if ( is_array( $layouts ) && count( $layouts ) > 1 ) { - - $active_layout = esc_attr( $layouts['active_layout'] ); - - echo ''; - - echo '
    '; - - echo ''; - - echo '
    '; - - foreach( $layouts as $key => $data ) { - - if ( $key == 'active_layout' ) - continue; - - echo ''; - - } - - } - - /* new layout wrapper */ - echo '
    '; - - /* add new layout */ - echo ''; - - echo ''; - - echo '
    '; - - echo '
    '; - - } - + /** + * Helper function to display Theme Options layouts form. + * + * @access public + * @since 2.0 + */ + function ot_theme_options_layouts_form() { + + echo '
    '; + + // Form nonce. + wp_nonce_field( 'option_tree_modify_layouts_form', 'option_tree_modify_layouts_nonce' ); + + // Get the saved layouts. + $layouts = get_option( ot_layouts_id() ); + + // Set active layout. + $active_layout = isset( $layouts['active_layout'] ) ? $layouts['active_layout'] : ''; + + if ( is_array( $layouts ) && 1 < count( $layouts ) ) { + + $active_layout = $layouts['active_layout']; + + echo ''; + + echo '
    '; + + echo ''; + } + + echo ''; + + echo '
    '; + + echo $hidden_safe; // phpcs:ignore + } + + /* new layout wrapper */ + echo '
    '; + + /* add new layout */ + echo ''; + + echo ''; + + echo '
    '; + + echo '
    '; + } } -/** - * Helper function to validate option ID's - * - * @param string $input The string to sanitize. - * @return string - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_sanitize_option_id' ) ) { - function ot_sanitize_option_id( $input ) { - - return preg_replace( '/[^a-z0-9]/', '_', trim( strtolower( $input ) ) ); - - } - + /** + * Helper function to sanitize the option ID's. + * + * @param string $input The string to sanitize. + * @return string + * + * @access public + * @since 2.0 + */ + function ot_sanitize_option_id( $input ) { + return preg_replace( '/[^a-z0-9]/', '_', trim( strtolower( $input ) ) ); + } } -/** - * Helper function to validate layout ID's - * - * @param string $input The string to sanitize. - * @return string - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_sanitize_layout_id' ) ) { - function ot_sanitize_layout_id( $input ) { - - return preg_replace( '/[^a-z0-9]/', '-', trim( strtolower( $input ) ) ); - - } - + /** + * Helper function to sanitize the layout ID's. + * + * @param string $input The string to sanitize. + * @return string + * + * @access public + * @since 2.0 + */ + function ot_sanitize_layout_id( $input ) { + return preg_replace( '/[^a-z0-9]/', '-', trim( strtolower( $input ) ) ); + } } -/** - * Convert choices array to string - * - * @return string - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_convert_array_to_string' ) ) { - function ot_convert_array_to_string( $input ) { - - if ( is_array( $input ) ) { - - foreach( $input as $k => $choice ) { - $choices[$k] = $choice['value'] . '|' . $choice['label']; - - if ( isset( $choice['src'] ) ) - $choices[$k].= '|' . $choice['src']; - - } - - return implode( ',', $choices ); - } - - return false; - } + /** + * Convert choices array to string. + * + * @param array $input The array to convert to a string. + * + * @return bool|string + * + * @access public + * @since 2.0 + */ + function ot_convert_array_to_string( $input ) { + + if ( is_array( $input ) ) { + + foreach ( $input as $k => $choice ) { + $choices[ $k ] = $choice['value'] . '|' . $choice['label']; + + if ( isset( $choice['src'] ) ) { + $choices[ $k ] .= '|' . $choice['src']; + } + } + + return implode( ',', $choices ); + } + + return false; + } } -/** - * Convert choices string to array - * - * @return array - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_convert_string_to_array' ) ) { - function ot_convert_string_to_array( $input ) { - - if ( '' !== $input ) { - - /* empty choices array */ - $choices = array(); - - /* exlode the string into an array */ - foreach( explode( ',', $input ) as $k => $choice ) { - - /* if ":" is splitting the string go deeper */ - if ( preg_match( '/\|/', $choice ) ) { - $split = explode( '|', $choice ); - $choices[$k]['value'] = trim( $split[0] ); - $choices[$k]['label'] = trim( $split[1] ); - - /* if radio image there are three values */ - if ( isset( $split[2] ) ) - $choices[$k]['src'] = trim( $split[2] ); - - } else { - $choices[$k]['value'] = trim( $choice ); - $choices[$k]['label'] = trim( $choice ); - } - - } - - /* return a formated choices array */ - return $choices; - - } - - return false; - - } + /** + * Convert choices string to array. + * + * @param string $input The string to convert to an array. + * + * @return bool|array + * + * @access public + * @since 2.0 + */ + function ot_convert_string_to_array( $input ) { + + if ( '' !== $input ) { + + // Empty choices array. + $choices = array(); + + // Exlode the string into an array. + foreach ( explode( ',', $input ) as $k => $choice ) { + + // If ":" is splitting the string go deeper. + if ( preg_match( '/\|/', $choice ) ) { + $split = explode( '|', $choice ); + + if ( 2 > count( $split ) ) { + continue; + } + + $choices[ $k ]['value'] = trim( $split[0] ); + $choices[ $k ]['label'] = trim( $split[1] ); + + // If radio image there are three values. + if ( isset( $split[2] ) ) { + $choices[ $k ]['src'] = trim( $split[2] ); + } + } else { + $choices[ $k ]['value'] = trim( $choice ); + $choices[ $k ]['label'] = trim( $choice ); + } + } + + // Return a formatted choices array. + return $choices; + } + + return false; + } } -/** - * Helper function - strpos() with arrays. - * - * @param string $haystack - * @param array $needles - * @return bool - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_strpos_array' ) ) { - function ot_strpos_array( $haystack, $needles = array() ) { - - foreach( $needles as $needle ) { - $pos = strpos( $haystack, $needle ); - if ( $pos !== false ) { - return true; - } - } - - return false; - } - + /** + * Helper function - strpos() in array recursively. + * + * @param string $haystack The string to search in. + * @param array $needles Keys to search for. + * @return bool + * + * @access public + * @since 2.0 + */ + function ot_strpos_array( $haystack, $needles = array() ) { + + foreach ( $needles as $needle ) { + if ( false !== strpos( $haystack, $needle ) ) { + return true; + } + } + + return false; + } } -/** - * Helper function - strpos() with arrays. - * - * @param string $haystack - * @param array $needles - * @return bool - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_array_keys_exists' ) ) { - - function ot_array_keys_exists( $array, $keys ) { - - foreach($keys as $k) { - if ( isset($array[$k]) ) { - return true; - } - } - - return false; - } - + + /** + * Helper function - array_key_exists() recursively. + * + * @param array $haystack The array to search in. + * @param array $needles Keys to search for. + * @return bool + * + * @access public + * @since 2.0 + */ + function ot_array_keys_exists( $haystack, $needles = array() ) { + + foreach ( $needles as $k ) { + if ( isset( $haystack[ $k ] ) ) { + return true; + } + } + + return false; + } } -/** - * Custom stripslashes from single value or array. - * - * @param mixed $input - * @return mixed - * - * @access public - * @since 2.0 - */ if ( ! function_exists( 'ot_stripslashes' ) ) { - function ot_stripslashes( $input ) { - - if ( is_array( $input ) ) { - - foreach( $input as &$val ) { - - if ( is_array( $val ) ) { - - $val = ot_stripslashes( $val ); - - } else { - - $val = stripslashes( trim( $val ) ); - - } - - } - - } else { - - $input = stripslashes( trim( $input ) ); - - } - - return $input; - - } - + /** + * Custom stripslashes from single value or array. + * + * @param mixed $input The string or array to stripslashes from. + * @return mixed + * + * @access public + * @since 2.0 + */ + function ot_stripslashes( $input ) { + + if ( is_array( $input ) ) { + + foreach ( $input as &$val ) { + + if ( is_array( $val ) ) { + $val = ot_stripslashes( $val ); + } else { + $val = stripslashes( trim( $val ) ); + } + } + } else { + $input = stripslashes( trim( $input ) ); + } + + return $input; + } } -/** - * Reverse wpautop. - * - * @param string $string The string to be filtered - * @return string - * - * @access public - * @since 2.0.9 - */ if ( ! function_exists( 'ot_reverse_wpautop' ) ) { - function ot_reverse_wpautop( $string = '' ) { - - /* return if string is empty */ - if ( trim( $string ) === '' ) - return ''; - - /* remove all new lines &

    tags */ - $string = str_replace( array( "\n", "

    " ), "", $string ); - - /* replace
    with \r */ - $string = str_replace( array( "
    ", "
    ", "
    " ), "\r", $string ); - - /* replace

    with \r\n */ - $string = str_replace( "

    ", "\r\n", $string ); - - /* return clean string */ - return trim( $string ); - - } - + /** + * Reverse wpautop. + * + * @param string $string The string to be filtered. + * @return string + * + * @access public + * @since 2.0.9 + */ + function ot_reverse_wpautop( $string = '' ) { + + // Return if string is empty. + if ( '' === trim( $string ) ) { + return ''; + } + + // Remove all new lines &

    tags. + $string = str_replace( array( "\n", '

    ' ), '', $string ); + + // Replace
    with \r. + $string = str_replace( array( '
    ', '
    ', '
    ' ), "\r", $string ); + + // Replace

    with \r\n. + $string = str_replace( '

    ', "\r\n", $string ); + + // Return clean string. + return trim( $string ); + } } -/** - * Returns an array of elements from start to limit, inclusive. - * - * Occasionally zero will be some impossibly large number to - * the "E" power when creating a range from negative to positive. - * This function attempts to fix that by setting that number back to "0". - * - * @param string $start First value of the sequence. - * @param string $limit The sequence is ended upon reaching the limit value. - * @param string $step If a step value is given, it will be used as the increment - * between elements in the sequence. step should be given as a - * positive number. If not specified, step will default to 1. - * @return array - * - * @access public - * @since 2.0.12 - */ -function ot_range( $start, $limit, $step = 1 ) { - - if ( $step < 0 ) - $step = 1; - - $range = range( $start, $limit, $step ); - - foreach( $range as $k => $v ) { - if ( strpos( $v, 'E' ) ) { - $range[$k] = 0; - } - } - - return $range; +if ( ! function_exists( 'ot_range' ) ) { + + /** + * Returns an array of elements from start to limit, inclusive. + * + * Occasionally zero will be some impossibly large number to + * the "E" power when creating a range from negative to positive. + * This function attempts to fix that by setting that number back to "0". + * + * @param string $start First value of the sequence. + * @param string $limit The sequence is ended upon reaching the limit value. + * @param int $step If a step value is given, it will be used as the increment + * between elements in the sequence. step should be given as a + * positive number. If not specified, step will default to 1. + * + * @return array + * + * @access public + * @since 2.0.12 + */ + function ot_range( $start, $limit, $step = 1 ) { + + if ( $step < 0 ) { + $step = 1; + } + + $range = range( $start, $limit, $step ); + + foreach ( $range as $k => $v ) { + if ( strpos( $v, 'E' ) ) { + $range[ $k ] = 0; + } + } + + return $range; + } } -/** - * Helper function to return encoded strings - * - * @return string - * - * @access public - * @since 2.0.13 - */ -function ot_encode( $value ) { - - $func = 'base64' . '_encode'; - return $func( $value ); - -} - -/** - * Helper function to return decoded strings - * - * @return string - * - * @access public - * @since 2.0.13 - */ -function ot_decode( $value ) { - - $func = 'base64' . '_decode'; - return $func( $value ); - -} - -/** - * Helper function to open a file - * - * @access public - * @since 2.0.13 - */ -function ot_file_open( $handle, $mode ) { - - $func = 'f' . 'open'; - return @$func( $handle, $mode ); - -} - -/** - * Helper function to close a file - * - * @access public - * @since 2.0.13 - */ -function ot_file_close( $handle ) { - - $func = 'f' . 'close'; - return $func( $handle ); - +if ( ! function_exists( 'ot_encode' ) ) { + + /** + * Helper function to return encoded strings. + * + * @param array $value The array to encode. + * + * @return string|bool + * + * @access public + * @since 2.0.13 + * @updated 2.7.0 + */ + function ot_encode( $value ) { + if ( is_array( $value ) ) { + return base64_encode( maybe_serialize( $value ) ); // phpcs:ignore + } + + return false; + } } -/** - * Helper function to write to an open file - * - * @access public - * @since 2.0.13 - */ -function ot_file_write( $handle, $string ) { - - $func = 'f' . 'write'; - return $func( $handle, $string ); - +if ( ! function_exists( 'ot_decode' ) ) { + + /** + * Helper function to return decoded arrays. + * + * @param string $value Encoded serialized array. + * + * @return array + * + * @access public + * @since 2.0.13 + */ + function ot_decode( $value ) { + + $fallback = array(); + $decoded = base64_decode( $value ); // phpcs:ignore + + // Search for an array. + preg_match( '/a:\d+:{.*?}/', $decoded, $array_matches, PREG_OFFSET_CAPTURE, 0 ); + + // Search for an object. + preg_match( '/O|C:\+?\d+:"[a-z0-9_]+":\+?\d+:/i', $decoded, $obj_matches, PREG_OFFSET_CAPTURE, 0 ); + + // Prevent object injection or non arrays. + if ( $obj_matches || ! $array_matches ) { + return $fallback; + } + + // Convert the options to an array. + $decoded = maybe_unserialize( $decoded ); + + if ( is_array( $decoded ) ) { + return $decoded; + } + + return $fallback; + } } -/** - * Helper function to filter standard option values. - * - * @param mixed $value Saved string or array value - * @param mixed $std Standard string or array value - * @return mixed String or array - * - * @access public - * @since 2.0.15 - */ -function ot_filter_std_value( $value = '', $std = '' ) { - - $std = maybe_unserialize( $std ); - - if ( is_array( $value ) && is_array( $std ) ) { - - foreach( $value as $k => $v ) { - - if ( '' == $value[$k] && isset( $std[$k] ) ) { - - $value[$k] = $std[$k]; - - } - - } - - } else if ( '' == $value && ! empty( $std ) ) { - - $value = $std; - - } - - return $value; - +if ( ! function_exists( 'ot_filter_std_value' ) ) { + + /** + * Helper function to filter standard option values. + * + * @param mixed $value Saved string or array value. + * @param mixed $std Standard string or array value. + * + * @return mixed String or array. + * + * @access public + * @since 2.0.15 + */ + function ot_filter_std_value( $value = '', $std = '' ) { + + if ( is_string( $std ) && ! empty( $std ) ) { + + // Search for an array. + preg_match( '/a:\d+:{.*?}/', $std, $array_matches, PREG_OFFSET_CAPTURE, 0 ); + + // Search for an object. + preg_match( '/O:\d+:"[a-z0-9_]+":\d+:{.*?}/i', $std, $obj_matches, PREG_OFFSET_CAPTURE, 0 ); + + // Prevent object injection. + if ( $array_matches && ! $obj_matches ) { + $std = maybe_unserialize( $std ); + } elseif ( $obj_matches ) { + $std = ''; + } + } + + if ( is_array( $value ) && is_array( $std ) ) { + foreach ( $value as $k => $v ) { + if ( '' === $value[ $k ] && isset( $std[ $k ] ) ) { + $value[ $k ] = $std[ $k ]; + } + } + } elseif ( '' === $value && ! empty( $std ) ) { + $value = $std; + } + + return $value; + } } -/** - * Helper function to set the Google fonts array. - * - * @param string $id The option ID. - * @param bool $value The option value - * @return void - * - * @access public - * @since 2.5.0 - */ -function ot_set_google_fonts( $id = '', $value = '' ) { - - $ot_set_google_fonts = get_theme_mod( 'ot_set_google_fonts', array() ); - - if ( is_array( $value ) && ! empty( $value ) ) { - $ot_set_google_fonts[$id] = $value; - } else if ( isset( $ot_set_google_fonts[$id] ) ) { - unset( $ot_set_google_fonts[$id] ); - } - - set_theme_mod( 'ot_set_google_fonts', $ot_set_google_fonts ); - +if ( ! function_exists( 'ot_set_google_fonts' ) ) { + + /** + * Helper function to set the Google fonts array. + * + * @param string $id The option ID. + * @param bool $value The option value. + * + * @access public + * @since 2.5.0 + */ + function ot_set_google_fonts( $id = '', $value = '' ) { + + $ot_set_google_fonts = get_theme_mod( 'ot_set_google_fonts', array() ); + + if ( is_array( $value ) && ! empty( $value ) ) { + $ot_set_google_fonts[ $id ] = $value; + } elseif ( isset( $ot_set_google_fonts[ $id ] ) ) { + unset( $ot_set_google_fonts[ $id ] ); + } + + set_theme_mod( 'ot_set_google_fonts', $ot_set_google_fonts ); + } } -/** - * Helper function to remove unused options from the Google fonts array. - * - * @param array $options The array of saved options. - * @return array - * - * @access public - * @since 2.5.0 - */ -function ot_update_google_fonts_after_save( $options ) { - - $ot_set_google_fonts = get_theme_mod( 'ot_set_google_fonts', array() ); - - foreach( $ot_set_google_fonts as $key => $set ) { - if ( ! isset( $options[$key] ) ) { - unset( $ot_set_google_fonts[$key] ); - } - } - set_theme_mod( 'ot_set_google_fonts', $ot_set_google_fonts ); - +if ( ! function_exists( 'ot_update_google_fonts_after_save' ) ) { + + /** + * Helper function to remove unused options from the Google fonts array. + * + * @param array $options The array of saved options. + * + * @access public + * @since 2.5.0 + */ + function ot_update_google_fonts_after_save( $options = array() ) { + + $ot_set_google_fonts = get_theme_mod( 'ot_set_google_fonts', array() ); + + foreach ( $ot_set_google_fonts as $key => $set ) { + if ( ! isset( $options[ $key ] ) ) { + unset( $ot_set_google_fonts[ $key ] ); + } + } + set_theme_mod( 'ot_set_google_fonts', $ot_set_google_fonts ); + } + + add_action( 'ot_after_theme_options_save', 'ot_update_google_fonts_after_save', 1 ); } -add_action( 'ot_after_theme_options_save', 'ot_update_google_fonts_after_save', 1 ); - -/** - * Helper function to fetch the Google fonts array. - * - * @param bool $normalize Whether or not to return a normalized array. Default 'true'. - * @param bool $force_rebuild Whether or not to force the array to be rebuilt. Default 'false'. - * @return array - * - * @access public - * @since 2.5.0 - */ -function ot_fetch_google_fonts( $normalize = true, $force_rebuild = false ) { - - /* Google Fonts cache key */ - $ot_google_fonts_cache_key = apply_filters( 'ot_google_fonts_cache_key', 'ot_google_fonts_cache' ); - - /* get the fonts from cache */ - $ot_google_fonts = apply_filters( 'ot_google_fonts_cache', get_transient( $ot_google_fonts_cache_key ) ); - - if ( $force_rebuild || ! is_array( $ot_google_fonts ) || empty( $ot_google_fonts ) ) { - - $ot_google_fonts = array(); - - /* API url and key */ - $ot_google_fonts_api_url = apply_filters( 'ot_google_fonts_api_url', 'https://www.googleapis.com/webfonts/v1/webfonts' ); - $ot_google_fonts_api_key = apply_filters( 'ot_google_fonts_api_key', 'AIzaSyB8G-4UtQr9fhDYTiNrDP40Y5GYQQKrNWI' ); - - /* API arguments */ - $ot_google_fonts_fields = apply_filters( 'ot_google_fonts_fields', array( 'family', 'variants', 'subsets' ) ); - $ot_google_fonts_sort = apply_filters( 'ot_google_fonts_sort', 'alpha' ); - - /* Initiate API request */ - $ot_google_fonts_query_args = array( - 'key' => $ot_google_fonts_api_key, - 'fields' => 'items(' . implode( ',', $ot_google_fonts_fields ) . ')', - 'sort' => $ot_google_fonts_sort - ); - - /* Build and make the request */ - $ot_google_fonts_query = esc_url_raw( add_query_arg( $ot_google_fonts_query_args, $ot_google_fonts_api_url ) ); - $ot_google_fonts_response = wp_safe_remote_get( $ot_google_fonts_query, array( 'sslverify' => false, 'timeout' => 15 ) ); - - /* continue if we got a valid response */ - if ( 200 == wp_remote_retrieve_response_code( $ot_google_fonts_response ) ) { - - if ( $response_body = wp_remote_retrieve_body( $ot_google_fonts_response ) ) { - - /* JSON decode the response body and cache the result */ - $ot_google_fonts_data = json_decode( trim( $response_body ), true ); - - if ( is_array( $ot_google_fonts_data ) && isset( $ot_google_fonts_data['items'] ) ) { - - $ot_google_fonts = $ot_google_fonts_data['items']; - - // Normalize the array key - $ot_google_fonts_tmp = array(); - foreach( $ot_google_fonts as $key => $value ) { - $id = remove_accents( $value['family'] ); - $id = strtolower( $id ); - $id = preg_replace( '/[^a-z0-9_\-]/', '', $id ); - $ot_google_fonts_tmp[$id] = $value; - } - - $ot_google_fonts = $ot_google_fonts_tmp; - set_theme_mod( 'ot_google_fonts', $ot_google_fonts ); - set_transient( $ot_google_fonts_cache_key, $ot_google_fonts, WEEK_IN_SECONDS ); - - } - - } - - } - - } - - return $normalize ? ot_normalize_google_fonts( $ot_google_fonts ) : $ot_google_fonts; - + +if ( ! function_exists( 'ot_fetch_google_fonts' ) ) { + + /** + * Helper function to fetch the Google fonts array. + * + * @param bool $normalize Whether or not to return a normalized array. Default 'true'. + * @param bool $force_rebuild Whether or not to force the array to be rebuilt. Default 'false'. + * + * @return array + * + * @access public + * @since 2.5.0 + */ + function ot_fetch_google_fonts( $normalize = true, $force_rebuild = false ) { + + // Google Fonts cache key. + $ot_google_fonts_cache_key = apply_filters( 'ot_google_fonts_cache_key', 'ot_google_fonts_cache' ); + + // Get the fonts from cache. + $ot_google_fonts = apply_filters( 'ot_google_fonts_cache', get_transient( $ot_google_fonts_cache_key ) ); + + if ( $force_rebuild || ! is_array( $ot_google_fonts ) || empty( $ot_google_fonts ) ) { + + $ot_google_fonts = array(); + + // API url and key. + $ot_google_fonts_api_url = apply_filters( 'ot_google_fonts_api_url', 'https://www.googleapis.com/webfonts/v1/webfonts' ); + $ot_google_fonts_api_key = apply_filters( 'ot_google_fonts_api_key', false ); + + if ( false === $ot_google_fonts_api_key ) { + return array(); + } + + // API arguments. + $ot_google_fonts_fields = apply_filters( + 'ot_google_fonts_fields', + array( + 'family', + 'variants', + 'subsets', + ) + ); + $ot_google_fonts_sort = apply_filters( 'ot_google_fonts_sort', 'alpha' ); + + // Initiate API request. + $ot_google_fonts_query_args = array( + 'key' => $ot_google_fonts_api_key, + 'fields' => 'items(' . implode( ',', $ot_google_fonts_fields ) . ')', + 'sort' => $ot_google_fonts_sort, + ); + + // Build and make the request. + $ot_google_fonts_query = esc_url_raw( add_query_arg( $ot_google_fonts_query_args, $ot_google_fonts_api_url ) ); + $ot_google_fonts_response = wp_safe_remote_get( + $ot_google_fonts_query, + array( + 'sslverify' => false, + 'timeout' => 15, + ) + ); + + // Continue if we got a valid response. + if ( 200 === wp_remote_retrieve_response_code( $ot_google_fonts_response ) ) { + + $response_body = wp_remote_retrieve_body( $ot_google_fonts_response ); + + if ( $response_body ) { + + // JSON decode the response body and cache the result. + $ot_google_fonts_data = json_decode( trim( $response_body ), true ); + + if ( is_array( $ot_google_fonts_data ) && isset( $ot_google_fonts_data['items'] ) ) { + + $ot_google_fonts = $ot_google_fonts_data['items']; + + // Normalize the array key. + $ot_google_fonts_tmp = array(); + foreach ( $ot_google_fonts as $key => $value ) { + if ( ! isset( $value['family'] ) ) { + continue; + } + + $id = preg_replace( '/[^a-z0-9_\-]/', '', strtolower( remove_accents( $value['family'] ) ) ); + + if ( $id ) { + $ot_google_fonts_tmp[ $id ] = $value; + } + } + + $ot_google_fonts = $ot_google_fonts_tmp; + set_theme_mod( 'ot_google_fonts', $ot_google_fonts ); + set_transient( $ot_google_fonts_cache_key, $ot_google_fonts, WEEK_IN_SECONDS ); + } + } + } + } + + return $normalize ? ot_normalize_google_fonts( $ot_google_fonts ) : $ot_google_fonts; + } } -/** - * Helper function to normalize the Google fonts array. - * - * @param array $google_fonts An array of fonts to nrmalize. - * @return array - * - * @access public - * @since 2.5.0 - */ -function ot_normalize_google_fonts( $google_fonts ) { - - $ot_normalized_google_fonts = array(); - - if ( is_array( $google_fonts ) && ! empty( $google_fonts ) ) { - - foreach( $google_fonts as $google_font ) { - - if( isset( $google_font['family'] ) ) { - - $id = str_replace( ' ', '+', $google_font['family'] ); - - $ot_normalized_google_fonts[ $id ] = array( - 'family' => $google_font['family'] - ); - - if( isset( $google_font['variants'] ) ) { - - $ot_normalized_google_fonts[ $id ]['variants'] = $google_font['variants']; - - } - - if( isset( $google_font['subsets'] ) ) { - - $ot_normalized_google_fonts[ $id ]['subsets'] = $google_font['subsets']; - - } - - } - - } - - } - - return $ot_normalized_google_fonts; - +if ( ! function_exists( 'ot_normalize_google_fonts' ) ) { + + /** + * Helper function to normalize the Google fonts array. + * + * @param array $google_fonts An array of fonts to normalize. + * + * @return array + * + * @access public + * @since 2.5.0 + */ + function ot_normalize_google_fonts( $google_fonts ) { + + $ot_normalized_google_fonts = array(); + + if ( is_array( $google_fonts ) && ! empty( $google_fonts ) ) { + + foreach ( $google_fonts as $google_font ) { + + if ( isset( $google_font['family'] ) ) { + + $id = str_replace( ' ', '+', $google_font['family'] ); + + $ot_normalized_google_fonts[ $id ] = array( + 'family' => $google_font['family'], + ); + + if ( isset( $google_font['variants'] ) ) { + $ot_normalized_google_fonts[ $id ]['variants'] = $google_font['variants']; + } + + if ( isset( $google_font['subsets'] ) ) { + $ot_normalized_google_fonts[ $id ]['subsets'] = $google_font['subsets']; + } + } + } + } + + return $ot_normalized_google_fonts; + } } -/** - * Helper function to register a WPML string - * - * @access public - * @since 2.1 - */ -function ot_wpml_register_string( $id, $value ) { - - if ( function_exists( 'icl_register_string' ) ) { - - icl_register_string( 'Theme Options', $id, $value ); - - } - +if ( ! function_exists( 'ot_wpml_register_string' ) ) { + + /** + * Helper function to register a WPML string. + * + * @param string $id The string ID. + * @param string $value The string value. + * + * @access public + * @since 2.1 + */ + function ot_wpml_register_string( $id, $value ) { + if ( function_exists( 'icl_register_string' ) ) { + icl_register_string( 'Theme Options', $id, $value ); + } + } } -/** - * Helper function to unregister a WPML string - * - * @access public - * @since 2.1 - */ -function ot_wpml_unregister_string( $id ) { - - if ( function_exists( 'icl_unregister_string' ) ) { - - icl_unregister_string( 'Theme Options', $id ); - - } - +if ( ! function_exists( 'ot_wpml_unregister_string' ) ) { + + /** + * Helper function to unregister a WPML string. + * + * @param string $id The string ID. + * + * @access public + * @since 2.1 + */ + function ot_wpml_unregister_string( $id ) { + if ( function_exists( 'icl_unregister_string' ) ) { + icl_unregister_string( 'Theme Options', $id ); + } + } } -/** - * Maybe migrate Settings - * - * @return void - * - * @access public - * @since 2.3.3 - */ if ( ! function_exists( 'ot_maybe_migrate_settings' ) ) { - function ot_maybe_migrate_settings() { - - // Filter the ID to migrate from - $settings_id = apply_filters( 'ot_migrate_settings_id', '' ); - - // Attempt to migrate Settings - if ( ! empty( $settings_id ) && get_option( ot_settings_id() ) === false && ot_settings_id() !== $settings_id ) { - - // Old settings - $settings = get_option( $settings_id ); - - // Check for array keys - if ( isset( $settings['sections'] ) && isset( $settings['settings'] ) ) { - - update_option( ot_settings_id(), $settings ); - - } - - } - - } - + /** + * Maybe migrate Settings. + * + * @access public + * @since 2.3.3 + */ + function ot_maybe_migrate_settings() { + + // Filter the ID to migrate from. + $settings_id = apply_filters( 'ot_migrate_settings_id', '' ); + + // Attempt to migrate Settings. + if ( ! empty( $settings_id ) && false === get_option( ot_settings_id() ) && ot_settings_id() !== $settings_id ) { + + // Old settings. + $settings = get_option( $settings_id ); + + // Check for array keys. + if ( isset( $settings['sections'] ) && isset( $settings['settings'] ) ) { + update_option( ot_settings_id(), $settings ); + } + } + } } -/** - * Maybe migrate Option - * - * @return void - * - * @access public - * @since 2.3.3 - */ if ( ! function_exists( 'ot_maybe_migrate_options' ) ) { - function ot_maybe_migrate_options() { - - // Filter the ID to migrate from - $options_id = apply_filters( 'ot_migrate_options_id', '' ); - - // Attempt to migrate Theme Options - if ( ! empty( $options_id ) && get_option( ot_options_id() ) === false && ot_options_id() !== $options_id ) { - - // Old options - $options = get_option( $options_id ); - - // Migrate to new ID - update_option( ot_options_id(), $options ); - - } - - } - + /** + * Maybe migrate Option. + * + * @access public + * @since 2.3.3 + */ + function ot_maybe_migrate_options() { + + // Filter the ID to migrate from. + $options_id = apply_filters( 'ot_migrate_options_id', '' ); + + // Attempt to migrate Theme Options. + if ( ! empty( $options_id ) && false === get_option( ot_options_id() ) && ot_options_id() !== $options_id ) { + + // Old options. + $options = get_option( $options_id ); + + // Migrate to new ID. + update_option( ot_options_id(), $options ); + } + } } -/** - * Maybe migrate Layouts - * - * @return void - * - * @access public - * @since 2.3.3 - */ if ( ! function_exists( 'ot_maybe_migrate_layouts' ) ) { - function ot_maybe_migrate_layouts() { - - // Filter the ID to migrate from - $layouts_id = apply_filters( 'ot_migrate_layouts_id', '' ); - - // Attempt to migrate Layouts - if ( ! empty( $layouts_id ) && get_option( ot_layouts_id() ) === false && ot_layouts_id() !== $layouts_id ) { - - // Old options - $layouts = get_option( $layouts_id ); - - // Migrate to new ID - update_option( ot_layouts_id(), $layouts ); - - } - - } - + /** + * Maybe migrate Layouts. + * + * @access public + * @since 2.3.3 + */ + function ot_maybe_migrate_layouts() { + + // Filter the ID to migrate from. + $layouts_id = apply_filters( 'ot_migrate_layouts_id', '' ); + + // Attempt to migrate Layouts. + if ( ! empty( $layouts_id ) && false === get_option( ot_layouts_id() ) && ot_layouts_id() !== $layouts_id ) { + + // Old options. + $layouts = get_option( $layouts_id ); + + // Migrate to new ID. + update_option( ot_layouts_id(), $layouts ); + } + } } -/** - * Returns an array with the post format gallery meta box. - * - * @param mixed $pages Excepts a comma separated string or array of - * post_types and is what tells the metabox where to - * display. Default 'post'. - * @return array - * - * @access public - * @since 2.4.0 - */ -function ot_meta_box_post_format_gallery( $pages = 'post' ) { - - if ( ! current_theme_supports( 'post-formats' ) || ! in_array( 'gallery', current( get_theme_support( 'post-formats' ) ) ) ) - return false; - - if ( is_string( $pages ) ) - $pages = explode( ',', $pages ); - - return apply_filters( 'ot_meta_box_post_format_gallery', array( - 'id' => 'ot-post-format-gallery', - 'title' => __( 'Gallery', 'option-tree' ), - 'desc' => '', - 'pages' => $pages, - 'context' => 'side', - 'priority' => 'low', - 'fields' => array( - array( - 'id' => '_format_gallery', - 'label' => '', - 'desc' => '', - 'std' => '', - 'type' => 'gallery', - 'class' => 'ot-gallery-shortcode' - ) - ) - ), $pages ); - +if ( ! function_exists( 'ot_meta_box_post_format_gallery' ) ) { + + /** + * Returns an array with the post format gallery meta box. + * + * @param mixed $pages Excepts a comma separated string or array of + * post_types and is what tells the metabox where to + * display. Default 'post'. + * @return array + * + * @access public + * @since 2.4.0 + */ + function ot_meta_box_post_format_gallery( $pages = 'post' ) { + + if ( ! current_theme_supports( 'post-formats' ) || ! in_array( 'gallery', current( get_theme_support( 'post-formats' ) ), true ) ) { + return false; + } + + if ( is_string( $pages ) ) { + $pages = explode( ',', $pages ); + } + + return apply_filters( + 'ot_meta_box_post_format_gallery', + array( + 'id' => 'ot-post-format-gallery', + 'title' => esc_html__( 'Gallery', 'option-tree' ), + 'desc' => '', + 'pages' => $pages, + 'context' => 'side', + 'priority' => 'low', + 'fields' => array( + array( + 'id' => '_format_gallery', + 'label' => '', + 'desc' => '', + 'std' => '', + 'type' => 'gallery', + 'class' => 'ot-gallery-shortcode', + ), + ), + ), + $pages + ); + } } -/** - * Returns an array with the post format link metabox. - * - * @param mixed $pages Excepts a comma separated string or array of - * post_types and is what tells the metabox where to - * display. Default 'post'. - * @return array - * - * @access public - * @since 2.4.0 - */ -function ot_meta_box_post_format_link( $pages = 'post' ) { - - if ( ! current_theme_supports( 'post-formats' ) || ! in_array( 'link', current( get_theme_support( 'post-formats' ) ) ) ) - return false; - - if ( is_string( $pages ) ) - $pages = explode( ',', $pages ); - - return apply_filters( 'ot_meta_box_post_format_link', array( - 'id' => 'ot-post-format-link', - 'title' => __( 'Link', 'option-tree' ), - 'desc' => '', - 'pages' => $pages, - 'context' => 'side', - 'priority' => 'low', - 'fields' => array( - array( - 'id' => '_format_link_url', - 'label' => '', - 'desc' => __( 'Link URL', 'option-tree' ), - 'std' => '', - 'type' => 'text' - ), - array( - 'id' => '_format_link_title', - 'label' => '', - 'desc' => __( 'Link Title', 'option-tree' ), - 'std' => '', - 'type' => 'text' - ) - ) - ), $pages ); - +if ( ! function_exists( 'ot_meta_box_post_format_link' ) ) { + + /** + * Returns an array with the post format link metabox. + * + * @param mixed $pages Excepts a comma separated string or array of + * post_types and is what tells the metabox where to + * display. Default 'post'. + * @return array + * + * @access public + * @since 2.4.0 + */ + function ot_meta_box_post_format_link( $pages = 'post' ) { + + if ( ! current_theme_supports( 'post-formats' ) || ! in_array( 'link', current( get_theme_support( 'post-formats' ) ), true ) ) { + return false; + } + + if ( is_string( $pages ) ) { + $pages = explode( ',', $pages ); + } + + return apply_filters( + 'ot_meta_box_post_format_link', + array( + 'id' => 'ot-post-format-link', + 'title' => esc_html__( 'Link', 'option-tree' ), + 'desc' => '', + 'pages' => $pages, + 'context' => 'side', + 'priority' => 'low', + 'fields' => array( + array( + 'id' => '_format_link_url', + 'label' => '', + 'desc' => esc_html__( 'Link URL', 'option-tree' ), + 'std' => '', + 'type' => 'text', + ), + array( + 'id' => '_format_link_title', + 'label' => '', + 'desc' => esc_html__( 'Link Title', 'option-tree' ), + 'std' => '', + 'type' => 'text', + ), + ), + ), + $pages + ); + } } -/** - * Returns an array with the post format quote metabox. - * - * @param mixed $pages Excepts a comma separated string or array of - * post_types and is what tells the metabox where to - * display. Default 'post'. - * @return array - * - * @access public - * @since 2.4.0 - */ -function ot_meta_box_post_format_quote( $pages = 'post' ) { - - if ( ! current_theme_supports( 'post-formats' ) || ! in_array( 'quote', current( get_theme_support( 'post-formats' ) ) ) ) - return false; - - if ( is_string( $pages ) ) - $pages = explode( ',', $pages ); - - return apply_filters( 'ot_meta_box_post_format_quote', array( - 'id' => 'ot-post-format-quote', - 'title' => __( 'Quote', 'option-tree' ), - 'desc' => '', - 'pages' => $pages, - 'context' => 'side', - 'priority' => 'low', - 'fields' => array( - array( - 'id' => '_format_quote_source_name', - 'label' => '', - 'desc' => __( 'Source Name (ex. author, singer, actor)', 'option-tree' ), - 'std' => '', - 'type' => 'text' - ), - array( - 'id' => '_format_quote_source_url', - 'label' => '', - 'desc' => __( 'Source URL', 'option-tree' ), - 'std' => '', - 'type' => 'text' - ), - array( - 'id' => '_format_quote_source_title', - 'label' => '', - 'desc' => __( 'Source Title (ex. book, song, movie)', 'option-tree' ), - 'std' => '', - 'type' => 'text' - ), - array( - 'id' => '_format_quote_source_date', - 'label' => '', - 'desc' => __( 'Source Date', 'option-tree' ), - 'std' => '', - 'type' => 'text' - ) - ) - ), $pages ); - +if ( ! function_exists( 'ot_meta_box_post_format_quote' ) ) { + + /** + * Returns an array with the post format quote metabox. + * + * @param mixed $pages Excepts a comma separated string or array of + * post_types and is what tells the metabox where to + * display. Default 'post'. + * @return array + * + * @access public + * @since 2.4.0 + */ + function ot_meta_box_post_format_quote( $pages = 'post' ) { + + if ( ! current_theme_supports( 'post-formats' ) || ! in_array( 'quote', current( get_theme_support( 'post-formats' ) ), true ) ) { + return false; + } + + if ( is_string( $pages ) ) { + $pages = explode( ',', $pages ); + } + + return apply_filters( + 'ot_meta_box_post_format_quote', + array( + 'id' => 'ot-post-format-quote', + 'title' => esc_html__( 'Quote', 'option-tree' ), + 'desc' => '', + 'pages' => $pages, + 'context' => 'side', + 'priority' => 'low', + 'fields' => array( + array( + 'id' => '_format_quote_source_name', + 'label' => '', + 'desc' => esc_html__( 'Source Name (ex. author, singer, actor)', 'option-tree' ), + 'std' => '', + 'type' => 'text', + ), + array( + 'id' => '_format_quote_source_url', + 'label' => '', + 'desc' => esc_html__( 'Source URL', 'option-tree' ), + 'std' => '', + 'type' => 'text', + ), + array( + 'id' => '_format_quote_source_title', + 'label' => '', + 'desc' => esc_html__( 'Source Title (ex. book, song, movie)', 'option-tree' ), + 'std' => '', + 'type' => 'text', + ), + array( + 'id' => '_format_quote_source_date', + 'label' => '', + 'desc' => esc_html__( 'Source Date', 'option-tree' ), + 'std' => '', + 'type' => 'text', + ), + ), + ), + $pages + ); + + } } -/** - * Returns an array with the post format video metabox. - * - * @param mixed $pages Excepts a comma separated string or array of - * post_types and is what tells the metabox where to - * display. Default 'post'. - * @return array - * - * @access public - * @since 2.4.0 - */ -function ot_meta_box_post_format_video( $pages = 'post' ) { - - if ( ! current_theme_supports( 'post-formats' ) || ! in_array( 'video', current( get_theme_support( 'post-formats' ) ) ) ) - return false; - - if ( is_string( $pages ) ) - $pages = explode( ',', $pages ); - - return apply_filters( 'ot_meta_box_post_format_video', array( - 'id' => 'ot-post-format-video', - 'title' => __( 'Video', 'option-tree' ), - 'desc' => '', - 'pages' => $pages, - 'context' => 'side', - 'priority' => 'low', - 'fields' => array( - array( - 'id' => '_format_video_embed', - 'label' => '', - 'desc' => sprintf( __( 'Embed video from services like Youtube, Vimeo, or Hulu. You can find a list of supported oEmbed sites in the %1$s. Alternatively, you could use the built-in %2$s shortcode.', 'option-tree' ), '' . __( 'Wordpress Codex', 'option-tree' ) .'', '[video]' ), - 'std' => '', - 'type' => 'textarea' - ) - ) - ), $pages ); - +if ( ! function_exists( 'ot_meta_box_post_format_video' ) ) { + + /** + * Returns an array with the post format video metabox. + * + * @param mixed $pages Excepts a comma separated string or array of + * post_types and is what tells the metabox where to + * display. Default 'post'. + * @return array + * + * @access public + * @since 2.4.0 + */ + function ot_meta_box_post_format_video( $pages = 'post' ) { + + if ( ! current_theme_supports( 'post-formats' ) || ! in_array( 'video', current( get_theme_support( 'post-formats' ) ), true ) ) { + return false; + } + + if ( is_string( $pages ) ) { + $pages = explode( ',', $pages ); + } + + /* translators: %1$s: link to WorPress Codex, %2$s: video shortcode */ + $string = esc_html__( 'Embed video from services like Youtube, Vimeo, or Hulu. You can find a list of supported oEmbed sites in the %1$s. Alternatively, you could use the built-in %2$s shortcode.', 'option-tree' ); + + return apply_filters( + 'ot_meta_box_post_format_video', + array( + 'id' => 'ot-post-format-video', + 'title' => __( 'Video', 'option-tree' ), + 'desc' => '', + 'pages' => $pages, + 'context' => 'side', + 'priority' => 'low', + 'fields' => array( + array( + 'id' => '_format_video_embed', + 'label' => '', + 'desc' => sprintf( $string, '' . esc_html__( 'WordPress Codex', 'option-tree' ) . '', '[video]' ), + 'std' => '', + 'type' => 'textarea', + ), + ), + ), + $pages + ); + } } -/** - * Returns an array with the post format audio metabox. - * - * @param mixed $pages Excepts a comma separated string or array of - * post_types and is what tells the metabox where to - * display. Default 'post'. - * @return array - * - * @access public - * @since 2.4.0 - */ -function ot_meta_box_post_format_audio( $pages = 'post' ) { - - if ( ! current_theme_supports( 'post-formats' ) || ! in_array( 'audio', current( get_theme_support( 'post-formats' ) ) ) ) - return false; - - if ( is_string( $pages ) ) - $pages = explode( ',', $pages ); - - return apply_filters( 'ot_meta_box_post_format_audio', array( - 'id' => 'ot-post-format-audio', - 'title' => __( 'Audio', 'option-tree' ), - 'desc' => '', - 'pages' => $pages, - 'context' => 'side', - 'priority' => 'low', - 'fields' => array( - array( - 'id' => '_format_audio_embed', - 'label' => '', - 'desc' => sprintf( __( 'Embed audio from services like SoundCloud and Rdio. You can find a list of supported oEmbed sites in the %1$s. Alternatively, you could use the built-in %2$s shortcode.', 'option-tree' ), '' . __( 'Wordpress Codex', 'option-tree' ) .'', '[audio]' ), - 'std' => '', - 'type' => 'textarea' - ) - ) - ), $pages ); - +if ( ! function_exists( 'ot_meta_box_post_format_audio' ) ) { + + /** + * Returns an array with the post format audio metabox. + * + * @param mixed $pages Excepts a comma separated string or array of + * post_types and is what tells the metabox where to + * display. Default 'post'. + * @return array + * + * @access public + * @since 2.4.0 + */ + function ot_meta_box_post_format_audio( $pages = 'post' ) { + + if ( ! current_theme_supports( 'post-formats' ) || ! in_array( 'audio', current( get_theme_support( 'post-formats' ) ), true ) ) { + return false; + } + + if ( is_string( $pages ) ) { + $pages = explode( ',', $pages ); + } + + /* translators: %1$s: link to WorPress Codex, %2$s: audio shortcode */ + $string = esc_html__( 'Embed audio from services like SoundCloud and Radio. You can find a list of supported oEmbed sites in the %1$s. Alternatively, you could use the built-in %2$s shortcode.', 'option-tree' ); + + return apply_filters( + 'ot_meta_box_post_format_audio', + array( + 'id' => 'ot-post-format-audio', + 'title' => esc_html__( 'Audio', 'option-tree' ), + 'desc' => '', + 'pages' => $pages, + 'context' => 'side', + 'priority' => 'low', + 'fields' => array( + array( + 'id' => '_format_audio_embed', + 'label' => '', + 'desc' => sprintf( $string, '' . esc_html__( 'WordPress Codex', 'option-tree' ) . '', '[audio]' ), + 'std' => '', + 'type' => 'textarea', + ), + ), + ), + $pages + ); + + } } -/** - * Returns the option type by ID. - * - * @param string $option_id The option ID - * @return string $settings_id The settings array ID - * @return string The option type. - * - * @access public - * @since 2.4.2 - */ if ( ! function_exists( 'ot_get_option_type_by_id' ) ) { - function ot_get_option_type_by_id( $option_id, $settings_id = '' ) { - - if ( empty( $settings_id ) ) { - - $settings_id = ot_settings_id(); - - } - - $settings = get_option( $settings_id, array() ); - - if ( isset( $settings['settings'] ) ) { - - foreach( $settings['settings'] as $value ) { - - if ( $option_id == $value['id'] && isset( $value['type'] ) ) { - - return $value['type']; - - } - - } - - } - - return false; - - } - + /** + * Returns the option type by ID. + * + * @param string $option_id The option ID. + * @param string $settings_id The settings array ID. + * @return string The option type. + * + * @access public + * @since 2.4.2 + */ + function ot_get_option_type_by_id( $option_id, $settings_id = '' ) { + + if ( empty( $settings_id ) ) { + $settings_id = ot_settings_id(); + } + + $settings = get_option( $settings_id, array() ); + + if ( isset( $settings['settings'] ) ) { + + foreach ( $settings['settings'] as $value ) { + + if ( $option_id === $value['id'] && isset( $value['type'] ) ) { + return $value['type']; + } + } + } + + return false; + } } -/** - * Build an array of potential Theme Options that could share terms - * - * @return array - * - * @access private - * @since 2.5.4 - */ -function _ot_settings_potential_shared_terms() { - - $options = array(); - $settings = get_option( ot_settings_id(), array() ); - $option_types = array( - 'category-checkbox', - 'category-select', - 'tag-checkbox', - 'tag-select', - 'taxonomy-checkbox', - 'taxonomy-select' - ); - - if ( isset( $settings['settings'] ) ) { - - foreach( $settings['settings'] as $value ) { - - if ( isset( $value['type'] ) ) { - - if ( $value['type'] == 'list-item' && isset( $value['settings'] ) ) { - - $saved = ot_get_option( $value['id'] ); - - foreach( $value['settings'] as $item ) { - - if ( isset( $value['id'] ) && isset( $item['type'] ) && in_array( $item['type'], $option_types ) ) { - $sub_options = array(); - - foreach( $saved as $sub_key => $sub_value ) { - if ( isset( $sub_value[$item['id']] ) ) { - $sub_options[$sub_key] = $sub_value[$item['id']]; - } - } - - if ( ! empty( $sub_options ) ) { - $options[] = array( - 'id' => $item['id'], - 'taxonomy' => $value['taxonomy'], - 'parent' => $value['id'], - 'value' => $sub_options - ); - } - } - - } - - } - - if ( in_array( $value['type'], $option_types ) ) { - $saved = ot_get_option( $value['id'] ); - if ( ! empty( $saved ) ) { - $options[] = array( - 'id' => $value['id'], - 'taxonomy' => $value['taxonomy'], - 'value' => $saved - ); - } - } - - } - - } - - } - - return $options; - +if ( ! function_exists( '_ot_settings_potential_shared_terms' ) ) { + + /** + * Build an array of potential Theme Options that could share terms. + * + * @return array + * + * @access private + * @since 2.5.4 + */ + function _ot_settings_potential_shared_terms() { + + $options = array(); + $settings = get_option( ot_settings_id(), array() ); + $option_types = array( + 'category-checkbox', + 'category-select', + 'tag-checkbox', + 'tag-select', + 'taxonomy-checkbox', + 'taxonomy-select', + ); + + if ( isset( $settings['settings'] ) ) { + + foreach ( $settings['settings'] as $value ) { + + if ( isset( $value['type'] ) ) { + + if ( 'list-item' === $value['type'] && isset( $value['settings'] ) ) { + + $saved = ot_get_option( $value['id'] ); + + foreach ( $value['settings'] as $item ) { + + if ( isset( $value['id'] ) && isset( $item['type'] ) && in_array( $item['type'], $option_types, true ) ) { + $sub_options = array(); + + foreach ( $saved as $sub_key => $sub_value ) { + if ( isset( $sub_value[ $item['id'] ] ) ) { + $sub_options[ $sub_key ] = $sub_value[ $item['id'] ]; + } + } + + if ( ! empty( $sub_options ) ) { + $options[] = array( + 'id' => $item['id'], + 'taxonomy' => $value['taxonomy'], + 'parent' => $value['id'], + 'value' => $sub_options, + ); + } + } + } + } + + if ( in_array( $value['type'], $option_types, true ) ) { + $saved = ot_get_option( $value['id'] ); + if ( ! empty( $saved ) ) { + $options[] = array( + 'id' => $value['id'], + 'taxonomy' => $value['taxonomy'], + 'value' => $saved, + ); + } + } + } + } + } + + return $options; + } } -/** - * Build an array of potential Meta Box options that could share terms - * - * @return array - * - * @access private - * @since 2.5.4 - */ -function _ot_meta_box_potential_shared_terms() { - global $ot_meta_boxes; - - $options = array(); - $settings = $ot_meta_boxes; - $option_types = array( - 'category-checkbox', - 'category-select', - 'tag-checkbox', - 'tag-select', - 'taxonomy-checkbox', - 'taxonomy-select' - ); - - foreach( $settings as $setting ) { - - if ( isset( $setting['fields'] ) ) { - - foreach( $setting['fields'] as $value ) { - - if ( isset( $value['type'] ) ) { - - if ( $value['type'] == 'list-item' && isset( $value['settings'] ) ) { - - $children = array(); - - foreach( $value['settings'] as $item ) { - - if ( isset( $value['id'] ) && isset( $item['type'] ) && in_array( $item['type'], $option_types ) ) { - - $children[$value['id']][] = $item['id']; - - } - - } - - if ( ! empty( $children[$value['id']] ) ) { - $options[] = array( - 'id' => $value['id'], - 'children' => $children[$value['id']], - 'taxonomy' => $value['taxonomy'], - ); - } - - } - - if ( in_array( $value['type'], $option_types ) ) { - - $options[] = array( - 'id' => $value['id'], - 'taxonomy' => $value['taxonomy'], - ); - - } - - } - - } - - } - - } - - return $options; - +if ( ! function_exists( '_ot_meta_box_potential_shared_terms' ) ) { + + /** + * Build an array of potential Meta Box options that could share terms. + * + * @return array + * + * @access private + * @since 2.5.4 + */ + function _ot_meta_box_potential_shared_terms() { + global $ot_meta_boxes; + + $options = array(); + $settings = $ot_meta_boxes; + $option_types = array( + 'category-checkbox', + 'category-select', + 'tag-checkbox', + 'tag-select', + 'taxonomy-checkbox', + 'taxonomy-select', + ); + + foreach ( $settings as $setting ) { + + if ( isset( $setting['fields'] ) ) { + + foreach ( $setting['fields'] as $value ) { + + if ( isset( $value['type'] ) ) { + + if ( 'list-item' === $value['type'] && isset( $value['settings'] ) ) { + + $children = array(); + + foreach ( $value['settings'] as $item ) { + + if ( isset( $value['id'] ) && isset( $item['type'] ) && in_array( $item['type'], $option_types, true ) ) { + $children[ $value['id'] ][] = $item['id']; + } + } + + if ( ! empty( $children[ $value['id'] ] ) ) { + $options[] = array( + 'id' => $value['id'], + 'children' => $children[ $value['id'] ], + 'taxonomy' => $value['taxonomy'], + ); + } + } + + if ( in_array( $value['type'], $option_types, true ) ) { + $options[] = array( + 'id' => $value['id'], + 'taxonomy' => $value['taxonomy'], + ); + } + } + } + } + } + + return $options; + } } -/** - * Update terms when a term gets split. - * - * @param int $term_id ID of the formerly shared term. - * @param int $new_term_id ID of the new term created for the $term_taxonomy_id. - * @param int $term_taxonomy_id ID for the term_taxonomy row affected by the split. - * @param string $taxonomy Taxonomy for the split term. - * @return void - * - * @access public - * @since 2.5.4 - */ -function ot_split_shared_term( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) { - - // Process the Theme Options - $settings = _ot_settings_potential_shared_terms(); - $old_options = get_option( ot_options_id(), array() ); - $new_options = $old_options; - - // Process the saved settings - if ( ! empty( $settings ) && ! empty( $old_options ) ) { - - // Loop over the Theme Options - foreach( $settings as $option ) { - - if ( ! is_array( $option['taxonomy'] ) ) { - $option['taxonomy'] = explode( ',', $option['taxonomy'] ); - } - - if ( ! in_array( $taxonomy, $option['taxonomy'] ) ) { - continue; - } - - // The option ID was found - if ( array_key_exists( $option['id'], $old_options ) || ( isset( $option['parent'] ) && array_key_exists( $option['parent'], $old_options ) ) ) { - - // This is a list item, we have to go deeper - if ( isset( $option['parent'] ) ) { - - // Loop over the array - foreach( $option['value'] as $key => $value ) { - - // The value is an array of IDs - if ( is_array( $value ) ) { - - // Loop over the sub array - foreach( $value as $sub_key => $sub_value ) { - - if ( $sub_value == $term_id ) { - - unset( $new_options[$option['parent']][$key][$option['id']][$sub_key] ); - $new_options[$option['parent']][$key][$option['id']][$new_term_id] = $new_term_id; - - } - - } - - } else if ( $value == $term_id ) { - - unset( $new_options[$option['parent']][$key][$option['id']] ); - $new_options[$option['parent']][$key][$option['id']] = $new_term_id; - - } - - } - - } else { - - // The value is an array of IDs - if ( is_array( $option['value'] ) ) { - - // Loop over the array - foreach( $option['value'] as $key => $value ) { - - // It's a single value, just replace it - if ( $value == $term_id ) { - - unset( $new_options[$option['id']][$key] ); - $new_options[$option['id']][$new_term_id] = $new_term_id; - - } - - } - - // It's a single value, just replace it - } else if ( $option['value'] == $term_id ) { - - $new_options[$option['id']] = $new_term_id; - - } - - } - - } - - } - - } - - // Options need to be updated - if ( $old_options !== $new_options ) { - update_option( ot_options_id(), $new_options ); - } - - // Process the Meta Boxes - $meta_settings = _ot_meta_box_potential_shared_terms(); - $option_types = array( - 'category-checkbox', - 'category-select', - 'tag-checkbox', - 'tag-select', - 'taxonomy-checkbox', - 'taxonomy-select' - ); - - if ( ! empty( $meta_settings ) ) { - $old_meta = array(); - - foreach( $meta_settings as $option ) { - - if ( ! is_array( $option['taxonomy'] ) ) { - $option['taxonomy'] = explode( ',', $option['taxonomy'] ); - } - - if ( ! in_array( $taxonomy, $option['taxonomy'] ) ) { - continue; - } - - if ( isset( $option['children'] ) ) { - $post_ids = get_posts( array( - 'fields' => 'ids', - 'meta_key' => $option['id'], - ) ); - - if ( $post_ids ) { - - foreach( $post_ids as $post_id ) { - - // Get the meta - $old_meta = get_post_meta( $post_id, $option['id'], true ); - $new_meta = $old_meta; - - // Has a saved value - if ( ! empty( $old_meta ) && is_array( $old_meta ) ) { - - // Loop over the array - foreach( $old_meta as $key => $value ) { - - foreach( $value as $sub_key => $sub_value ) { - - if ( in_array( $sub_key, $option['children'] ) ) { - - // The value is an array of IDs - if ( is_array( $sub_value ) ) { - - // Loop over the array - foreach( $sub_value as $sub_sub_key => $sub_sub_value ) { - - // It's a single value, just replace it - if ( $sub_sub_value == $term_id ) { - - unset( $new_meta[$key][$sub_key][$sub_sub_key] ); - $new_meta[$key][$sub_key][$new_term_id] = $new_term_id; - - } - - } - - // It's a single value, just replace it - } else if ( $sub_value == $term_id ) { - - $new_meta[$key][$sub_key] = $new_term_id; - - } - - } - - } - - } - - // Update - if ( $old_meta !== $new_meta ) { - - update_post_meta( $post_id, $option['id'], $new_meta, $old_meta ); - - } - - } - - } - - } - - } else { - $post_ids = get_posts( array( - 'fields' => 'ids', - 'meta_query' => array( - 'key' => $option['id'], - 'value' => $term_id, - 'compare' => 'IN' - ), - ) ); - - if ( $post_ids ) { - - foreach( $post_ids as $post_id ) { - - // Get the meta - $old_meta = get_post_meta( $post_id, $option['id'], true ); - $new_meta = $old_meta; - - // Has a saved value - if ( ! empty( $old_meta ) ) { - - // The value is an array of IDs - if ( is_array( $old_meta ) ) { - - // Loop over the array - foreach( $old_meta as $key => $value ) { - - // It's a single value, just replace it - if ( $value == $term_id ) { - - unset( $new_meta[$key] ); - $new_meta[$new_term_id] = $new_term_id; - - } - - } - - // It's a single value, just replace it - } else if ( $old_meta == $term_id ) { - - $new_meta = $new_term_id; - - } - - // Update - if ( $old_meta !== $new_meta ) { - - update_post_meta( $post_id, $option['id'], $new_meta, $old_meta ); - - } - - } - - } - - } - - } - - } - - } - +if ( ! function_exists( 'ot_split_shared_term' ) ) { + + /** + * Update terms when a term gets split. + * + * @param int $term_id ID of the formerly shared term. + * @param int $new_term_id ID of the new term created for the $term_taxonomy_id. + * @param int $term_taxonomy_id ID for the term_taxonomy row affected by the split. + * @param string $taxonomy Taxonomy for the split term. + * + * @access public + * @since 2.5.4 + */ + function ot_split_shared_term( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) { + unset( $term_taxonomy_id ); + + // Process the Theme Options. + $settings = _ot_settings_potential_shared_terms(); + $old_options = get_option( ot_options_id(), array() ); + $new_options = $old_options; + + // Process the saved settings. + if ( ! empty( $settings ) && ! empty( $old_options ) ) { + + // Loop over the Theme Options. + foreach ( $settings as $option ) { + + if ( ! is_array( $option['taxonomy'] ) ) { + $option['taxonomy'] = explode( ',', $option['taxonomy'] ); + } + + if ( ! in_array( $taxonomy, $option['taxonomy'], true ) ) { + continue; + } + + // The option ID was found. + if ( array_key_exists( $option['id'], $old_options ) || ( isset( $option['parent'] ) && array_key_exists( $option['parent'], $old_options ) ) ) { + + // This is a list item, we have to go deeper. + if ( isset( $option['parent'] ) ) { + + // Loop over the array. + foreach ( $option['value'] as $key => $value ) { + + // The value is an array of IDs. + if ( is_array( $value ) ) { + + // Loop over the sub array. + foreach ( $value as $sub_key => $sub_value ) { + + if ( $sub_value === $term_id ) { + unset( $new_options[ $option['parent'] ][ $key ][ $option['id'] ][ $sub_key ] ); + $new_options[ $option['parent'] ][ $key ][ $option['id'] ][ $new_term_id ] = $new_term_id; + } + } + } elseif ( $value === $term_id ) { + unset( $new_options[ $option['parent'] ][ $key ][ $option['id'] ] ); + $new_options[ $option['parent'] ][ $key ][ $option['id'] ] = $new_term_id; + } + } + } else { + + // The value is an array of IDs. + if ( is_array( $option['value'] ) ) { + + // Loop over the array. + foreach ( $option['value'] as $key => $value ) { + + // It's a single value, just replace it. + if ( $value === $term_id ) { + unset( $new_options[ $option['id'] ][ $key ] ); + $new_options[ $option['id'] ][ $new_term_id ] = $new_term_id; + } + } + + // It's a single value, just replace it. + } elseif ( $option['value'] === $term_id ) { + $new_options[ $option['id'] ] = $new_term_id; + } + } + } + } + } + + // Options need to be updated. + if ( $old_options !== $new_options ) { + update_option( ot_options_id(), $new_options ); + } + + // Process the Meta Boxes. + $meta_settings = _ot_meta_box_potential_shared_terms(); + + if ( ! empty( $meta_settings ) ) { + + foreach ( $meta_settings as $option ) { + + if ( ! is_array( $option['taxonomy'] ) ) { + $option['taxonomy'] = explode( ',', $option['taxonomy'] ); + } + + if ( ! in_array( $taxonomy, $option['taxonomy'], true ) ) { + continue; + } + + if ( isset( $option['children'] ) ) { + $post_ids = get_posts( + array( + 'fields' => 'ids', + 'meta_key' => $option['id'], // phpcs:ignore + ) + ); + + if ( $post_ids ) { + + foreach ( $post_ids as $post_id ) { + + // Get the meta. + $old_meta = get_post_meta( $post_id, $option['id'], true ); + $new_meta = $old_meta; + + // Has a saved value. + if ( ! empty( $old_meta ) && is_array( $old_meta ) ) { + + // Loop over the array. + foreach ( $old_meta as $key => $value ) { + + foreach ( $value as $sub_key => $sub_value ) { + + if ( in_array( $sub_key, $option['children'], true ) ) { + + // The value is an array of IDs. + if ( is_array( $sub_value ) ) { + + // Loop over the array. + foreach ( $sub_value as $sub_sub_key => $sub_sub_value ) { + + // It's a single value, just replace it. + if ( $sub_sub_value === $term_id ) { + unset( $new_meta[ $key ][ $sub_key ][ $sub_sub_key ] ); + $new_meta[ $key ][ $sub_key ][ $new_term_id ] = $new_term_id; + } + } + + // It's a single value, just replace it. + } elseif ( $sub_value === $term_id ) { + $new_meta[ $key ][ $sub_key ] = $new_term_id; + } + } + } + } + + // Update. + if ( $old_meta !== $new_meta ) { + update_post_meta( $post_id, $option['id'], $new_meta, $old_meta ); + } + } + } + } + } else { + $post_ids = get_posts( + array( + 'fields' => 'ids', + 'meta_query' => array( // phpcs:ignore + 'key' => $option['id'], + 'value' => $term_id, + 'compare' => 'IN', + ), + ) + ); + + if ( $post_ids ) { + + foreach ( $post_ids as $post_id ) { + + // Get the meta. + $old_meta = get_post_meta( $post_id, $option['id'], true ); + $new_meta = $old_meta; + + // Has a saved value. + if ( ! empty( $old_meta ) ) { + + // The value is an array of IDs. + if ( is_array( $old_meta ) ) { + + // Loop over the array. + foreach ( $old_meta as $key => $value ) { + + // It's a single value, just replace it. + if ( $value === $term_id ) { + unset( $new_meta[ $key ] ); + $new_meta[ $new_term_id ] = $new_term_id; + } + } + + // It's a single value, just replace it. + } elseif ( $old_meta === $term_id ) { + $new_meta = $new_term_id; + } + + // Update. + if ( $old_meta !== $new_meta ) { + update_post_meta( $post_id, $option['id'], $new_meta, $old_meta ); + } + } + } + } + } + } + } + } + + add_action( 'split_shared_term', 'ot_split_shared_term', 10, 4 ); } -add_action( 'split_shared_term', 'ot_split_shared_term', 10, 4 ); - -/* End of file ot-functions-admin.php */ -/* Location: ./includes/ot-functions-admin.php */ \ No newline at end of file