diff -r 346c88efed21 -r 5e2f62d02dcd wp/wp-content/plugins/option-tree/includes/ot-functions-admin.php --- a/wp/wp-content/plugins/option-tree/includes/ot-functions-admin.php Mon Jun 08 16:11:51 2015 +0000 +++ b/wp/wp-content/plugins/option-tree/includes/ot-functions-admin.php Tue Jun 09 03:35:32 2015 +0200 @@ -26,7 +26,7 @@ function ot_register_theme_options_page() { /* get the settings array */ - $get_settings = get_option( 'option_tree_settings' ); + $get_settings = get_option( ot_settings_id() ); /* sections array */ $sections = isset( $get_settings['sections'] ) ? $get_settings['sections'] : array(); @@ -42,7 +42,7 @@ ot_register_settings( array( array( - 'id' => 'option_tree', + 'id' => ot_options_id(), 'pages' => array( array( 'id' => 'ot_theme_options', @@ -56,10 +56,9 @@ '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' ) ), - 'screen_icon' => 'themes', - 'contextual_help' => $contextual_help, - 'sections' => $sections, - 'settings' => $settings + '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 ) ) ) ) @@ -67,7 +66,7 @@ ); // Filters the options.php to add the minimum user capabilities. - add_filter( 'option_page_capability_option_tree', create_function( '$caps', "return '$caps';" ), 999 ); + add_filter( 'option_page_capability_' . ot_options_id(), create_function( '$caps', "return '$caps';" ), 999 ); } @@ -88,7 +87,21 @@ 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( @@ -97,7 +110,7 @@ 'menu_title' => __( 'OptionTree', 'option-tree' ), 'capability' => 'edit_theme_options', 'menu_slug' => 'ot-settings', - 'icon_url' => OT_URL . '/assets/images/ot-logo-mini.png', + 'icon_url' => null, 'position' => 61, 'hidden_page' => true ), @@ -114,7 +127,6 @@ 'reset_message' => __( 'Theme Options reset.', 'option-tree' ), 'button_text' => __( 'Save Settings', 'option-tree' ), 'show_buttons' => false, - 'screen_icon' => 'themes', 'sections' => array( array( 'id' => 'create_setting', @@ -209,7 +221,6 @@ 'reset_message' => __( 'Theme Options reset.', 'option-tree' ), 'button_text' => __( 'Save Settings', 'option-tree' ), 'show_buttons' => false, - 'screen_icon' => 'themes', 'sections' => array( array( 'id' => 'creating_options', @@ -371,7 +382,7 @@ // Register the pages. ot_register_settings( array( array( - 'id' => 'option_tree_settings', + 'id' => ot_settings_id(), 'pages' => $ot_register_pages_array ) ) @@ -400,7 +411,7 @@ if ( apply_filters( 'ot_theme_options_menu_slug', 'ot-theme-options' ) == $page && $updated ) { /* grab a copy of the theme options */ - $options = get_option( 'option_tree' ); + $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 ); @@ -466,37 +477,254 @@ $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 ) ) { + 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', __( 'The Colorpicker only allows valid hexadecimal values.', 'option-tree' ), 'error' ); + 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 ( in_array( $type, array( 'css', 'text', 'textarea', 'textarea-simple' ) ) ) { + + } 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 ) { - $input = sanitize_text_field( $input ); - + 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 ); @@ -506,7 +734,7 @@ } } - + /** * Setup the default admin styles * @@ -518,9 +746,46 @@ 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' ); + } } @@ -540,7 +805,10 @@ 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(); @@ -548,37 +816,63 @@ /* Legacy Thickbox */ add_thickbox(); } - - /* load the colorpicker */ - wp_enqueue_script( 'ot-colorpicker-js', OT_URL . 'assets/js/ot-colorpicker.js', array( 'jquery' ), OT_VERSION ); - + /* 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', 'media-upload', 'thickbox' ), OT_VERSION ); - + 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' ), - 'upload_text' => __( 'Send to OptionTree', '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' ) + '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' ); } } /** - * Returns the ID of a custom post type by post_name. + * Returns the ID of a custom post type by post_title. * * @uses get_results() * @@ -590,9 +884,27 @@ if ( ! function_exists( 'ot_get_media_post_ID' ) ) { function ot_get_media_post_ID() { - global $wpdb; - - return $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE `post_name` = 'media' AND `post_type` = 'option-tree' AND `post_status` = 'private'" ); + + // 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; } @@ -612,7 +924,8 @@ function ot_create_media_post() { - register_post_type( 'option-tree', array( + $regsiter_post_type = 'register_' . 'post_type'; + $regsiter_post_type( 'option-tree', array( 'labels' => array( 'name' => __( 'Option Tree', 'option-tree' ) ), 'public' => false, 'show_ui' => false, @@ -634,6 +947,7 @@ /* 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'; @@ -659,15 +973,16 @@ if ( ! function_exists( 'ot_default_settings' ) ) { function ot_default_settings() { - global $wpdb, $table_prefix; - - if ( ! get_option( 'option_tree_settings' ) ) { + global $wpdb; + + if ( ! get_option( ot_settings_id() ) ) { $section_count = 0; $settings_count = 0; $settings = array(); - - if ( mysql_num_rows( mysql_query( "SHOW TABLES LIKE '{$table_prefix}option_tree'" ) ) == 1 && $old_settings = $wpdb->get_results( "SELECT * FROM {$table_prefix}option_tree ORDER BY item_sort ASC" ) ) { + $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 ) { @@ -697,7 +1012,7 @@ /* textarea rows */ $rows = ''; - if ( in_array( $settings['settings'][$settings_count]['type'], array( 'css', 'textarea' ) ) ) { + if ( in_array( $settings['settings'][$settings_count]['type'], array( 'css', 'javascript', 'textarea' ) ) ) { if ( (int) $setting->item_options > 0 ) { $rows = (int) $setting->item_options; } else { @@ -771,10 +1086,10 @@ } /* update the settings array */ - update_option( 'option_tree_settings', $settings ); + update_option( ot_settings_id(), $settings ); /* get option tree array */ - $options = get_option( 'option_tree' ); + $options = get_option( ot_options_id() ); /* validate options */ if ( is_array( $options ) ) { @@ -795,7 +1110,7 @@ do_action( 'ot_before_theme_options_save', $options ); /* update the option tree array */ - update_option( 'option_tree', $options ); + update_option( ot_options_id(), $options ); } @@ -818,7 +1133,7 @@ function ot_save_css( $options ) { /* grab a copy of the settings */ - $settings = get_option( 'option_tree_settings' ); + $settings = get_option( ot_settings_id() ); /* has settings */ if ( isset( $settings['settings'] ) ) { @@ -953,7 +1268,7 @@ } /* update settings */ - update_option( 'option_tree_settings', $settings ); + update_option( ot_settings_id(), $settings ); /* set message */ $message = 'success'; @@ -961,7 +1276,7 @@ } /* redirect */ - wp_redirect( add_query_arg( array( 'action' => 'import-xml', 'message' => $message ), $_POST['_wp_http_referer'] ) ); + wp_redirect( esc_url_raw( add_query_arg( array( 'action' => 'import-xml', 'message' => $message ), $_POST['_wp_http_referer'] ) ) ); exit; } @@ -977,12 +1292,12 @@ /* is array: save & show success message */ if ( is_array( $textarea ) ) { - update_option( 'option_tree_settings', $textarea ); + update_option( ot_settings_id(), $textarea ); $message = 'success'; } /* redirect */ - wp_redirect( add_query_arg( array( 'action' => 'import-settings', 'message' => $message ), $_POST['_wp_http_referer'] ) ); + wp_redirect( esc_url_raw( add_query_arg( array( 'action' => 'import-settings', 'message' => $message ), $_POST['_wp_http_referer'] ) ) ); exit; } @@ -997,7 +1312,7 @@ $options = isset( $_POST['import_data'] ) ? unserialize( ot_decode( $_POST['import_data'] ) ) : ''; /* get settings array */ - $settings = get_option( 'option_tree_settings' ); + $settings = get_option( ot_settings_id() ); /* has options */ if ( is_array( $options ) ) { @@ -1023,14 +1338,14 @@ do_action( 'ot_before_theme_options_save', $options ); /* update the option tree array */ - update_option( 'option_tree', $options ); + update_option( ot_options_id(), $options ); $message = 'success'; } /* redirect accordingly */ - wp_redirect( add_query_arg( array( 'action' => 'import-data', 'message' => $message ), $_POST['_wp_http_referer'] ) ); + wp_redirect( esc_url_raw( add_query_arg( array( 'action' => 'import-data', 'message' => $message ), $_POST['_wp_http_referer'] ) ) ); exit; } @@ -1045,7 +1360,7 @@ $layouts = isset( $_POST['import_layouts'] ) ? unserialize( ot_decode( $_POST['import_layouts'] ) ) : ''; /* get settings array */ - $settings = get_option( 'option_tree_settings' ); + $settings = get_option( ot_settings_id() ); /* has layouts */ if ( is_array( $layouts ) ) { @@ -1086,19 +1401,19 @@ /* execute the action hook and pass the theme options to it */ do_action( 'ot_before_theme_options_save', $new_options ); - update_option( 'option_tree', $new_options ); + update_option( ot_options_id(), $new_options ); } /* update the option tree layouts array */ - update_option( 'option_tree_layouts', $layouts ); + update_option( ot_layouts_id(), $layouts ); $message = 'success'; } /* redirect accordingly */ - wp_redirect( add_query_arg( array( 'action' => 'import-layouts', 'message' => $message ), $_POST['_wp_http_referer'] ) ); + wp_redirect( esc_url_raw( add_query_arg( array( 'action' => 'import-layouts', 'message' => $message ), $_POST['_wp_http_referer'] ) ) ); exit; } @@ -1190,7 +1505,7 @@ /* textarea rows */ $rows = ''; - if ( in_array( $settings['settings'][$settings_count]['type'], array( 'css', 'textarea' ) ) ) { + if ( in_array( $settings['settings'][$settings_count]['type'], array( 'css', 'javascript', 'textarea' ) ) ) { if ( (int) $value->item_options > 0 ) { $rows = (int) $value->item_options; } else { @@ -1259,7 +1574,16 @@ $contextual_help = ''; $sections = ''; $settings = ''; - $option_tree_settings = get_option( 'option_tree_settings', array() ); + $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 "); @@ -1273,13 +1597,13 @@ $help = ''; foreach( $option_tree_settings['contextual_help']['content'] as $value ) { $_id = isset( $value['id'] ) ? $value['id'] : ''; - $_title = isset( $value['title'] ) ? str_replace( "'", "\'", $value['title'] ) : ''; - $_content = isset( $value['content'] ) ? html_entity_decode( str_replace( "'", "\'", $value['content'] ) ) : ''; + $_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' + 'title' => $_title, + 'content' => $_content ),"; } $help = substr_replace( $help, '' , -1 ); @@ -1291,7 +1615,7 @@ /* build contextual help sidebar */ if ( isset( $option_tree_settings['contextual_help']['sidebar'] ) ) { $contextual_help.= " - 'sidebar' => '" . html_entity_decode( str_replace( "'", "\'", $option_tree_settings['contextual_help']['sidebar'] ) ) . "'"; + '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 */ @@ -1305,11 +1629,11 @@ if ( isset( $option_tree_settings['sections'] ) ) { foreach( $option_tree_settings['sections'] as $value ) { $_id = isset( $value['id'] ) ? $value['id'] : ''; - $_title = isset( $value['title'] ) ? str_replace( "'", "\'", $value['title'] ) : ''; + $_title = ot_I18n_string( isset( $value['title'] ) ? str_replace( "'", "\'", $value['title'] ) : '' ); $sections.= " array( 'id' => '$_id', - 'title' => '$_title' + 'title' => $_title ),"; } $sections = substr_replace( $sections, '' , -1 ); @@ -1326,8 +1650,8 @@ if ( isset( $option_tree_settings['settings'] ) ) { foreach( $option_tree_settings['settings'] as $value ) { $_id = isset( $value['id'] ) ? $value['id'] : ''; - $_label = isset( $value['label'] ) ? str_replace( "'", "\'", $value['label'] ) : ''; - $_desc = isset( $value['desc'] ) ? str_replace( "'", "\'", $value['desc'] ) : ''; + $_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'] : ''; @@ -1336,24 +1660,26 @@ $_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 = isset( $choice['label'] ) ? str_replace( "'", "\'", $choice['label'] ) : ''; + $_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', + 'label' => $_choice_label, 'src' => '$_choice_src' ),"; } $choices = substr_replace( $choices, '' , -1 ); $choices = ", 'choices' => array( $choices - ),"; + )"; } $std = "'$_std'"; @@ -1371,8 +1697,8 @@ if ( isset( $value['settings'] ) && ! empty( $value['settings'] ) ) { foreach( $value['settings'] as $setting ) { $_setting_id = isset( $setting['id'] ) ? $setting['id'] : ''; - $_setting_label = isset( $setting['label'] ) ? str_replace( "'", "\'", $setting['label'] ) : ''; - $_setting_desc = isset( $setting['desc'] ) ? str_replace( "'", "\'", $setting['desc'] ) : ''; + $_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'] : ''; @@ -1380,24 +1706,26 @@ $_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 = isset( $setting_choice['label'] ) ? str_replace( "'", "\'", $setting_choice['label'] ) : ''; + $_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', + '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'"; @@ -1414,15 +1742,17 @@ $setting_settings.= " array( 'id' => '$_setting_id', - 'label' => '$_setting_label', - 'desc' => '$_setting_desc', + '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'$setting_choices + 'class' => '$_setting_class', + 'condition' => '$_setting_condition', + 'operator' => '$_setting_operator'$setting_choices ),"; } $setting_settings = substr_replace( $setting_settings, '' , -1 ); @@ -1434,8 +1764,8 @@ $settings.= " array( 'id' => '$_id', - 'label' => '$_label', - 'desc' => '$_desc', + 'label' => $_label, + 'desc' => $_desc, 'std' => $std, 'type' => '$_type', 'section' => '$_section', @@ -1443,7 +1773,9 @@ 'post_type' => '$_post_type', 'taxonomy' => '$_taxonomy', 'min_max_step'=> '$_min_max_step', - 'class' => '$_class'$choices$setting_settings + 'class' => '$_class', + 'condition' => '$_condition', + 'operator' => '$_operator'$choices$setting_settings ),"; } $settings = substr_replace( $settings, '' , -1 ); @@ -1460,16 +1792,21 @@ /** * Initialize the custom theme options. */ -add_action( 'admin_init', 'custom_theme_options' ); +add_action( 'init', 'custom_theme_options' ); /** * Build the custom settings & update OptionTree. */ function custom_theme_options() { + + /* OptionTree is not loaded yet, or this is not an admin request */ + if ( ! function_exists( 'ot_settings_id' ) || ! is_admin() ) + return false; + /** * Get a copy of the saved settings array. */ - \$saved_settings = get_option( 'option_tree_settings', array() ); + \$saved_settings = get_option( ot_settings_id(), array() ); /** * Custom settings array that will eventually be @@ -1479,13 +1816,17 @@ ); /* allow settings to be filtered before saving */ - \$custom_settings = apply_filters( 'option_tree_settings_args', \$custom_settings ); + \$custom_settings = apply_filters( ot_settings_id() . '_args', \$custom_settings ); /* settings are not the same update the DB */ if ( \$saved_settings !== \$custom_settings ) { - update_option( 'option_tree_settings', \$custom_settings ); + update_option( ot_settings_id(), \$custom_settings ); } + /* Lets OptionTree know the UI Builder is being overridden */ + global \$ot_has_custom_theme_options; + \$ot_has_custom_theme_options = true; + }"; echo $content; @@ -1510,7 +1851,7 @@ if ( isset( $_POST['option_tree_settings_nonce'] ) && wp_verify_nonce( $_POST['option_tree_settings_nonce'], 'option_tree_settings_form' ) ) { /* settings value */ - $settings = isset( $_POST['option_tree_settings'] ) ? $_POST['option_tree_settings'] : ''; + $settings = isset( $_POST[ot_settings_id()] ) ? $_POST[ot_settings_id()] : ''; /* validate sections */ if ( isset( $settings['sections'] ) ) { @@ -1634,8 +1975,8 @@ /* WPML unregister ID's that have been removed */ if ( function_exists( 'icl_unregister_string' ) ) { - $current = get_option( 'option_tree_settings' ); - $options = get_option( 'option_tree' ); + $current = get_option( ot_settings_id() ); + $options = get_option( ot_options_id() ); if ( isset( $current['settings'] ) ) { @@ -1669,6 +2010,18 @@ } } + + } 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 { @@ -1684,13 +2037,13 @@ } - update_option( 'option_tree_settings', $settings ); + update_option( ot_settings_id(), $settings ); $message = 'success'; } /* redirect */ - wp_redirect( add_query_arg( array( 'action' => 'save-settings', 'message' => $message ), $_POST['_wp_http_referer'] ) ); + wp_redirect( esc_url_raw( add_query_arg( array( 'action' => 'save-settings', 'message' => $message ), $_POST['_wp_http_referer'] ) ) ); exit; } @@ -1833,10 +2186,10 @@ 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( 'option_tree_layouts' ); + $option_tree_layouts = get_option( ot_layouts_id() ); /* new layouts value */ - $layouts = isset( $_POST['option_tree_layouts'] ) ? $_POST['option_tree_layouts'] : ''; + $layouts = isset( $_POST[ot_layouts_id()] ) ? $_POST[ot_layouts_id()] : ''; /* rebuild layout array */ $rebuild = array(); @@ -1852,7 +2205,7 @@ /* 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( 'option_tree' ) ) ); + $rebuild[$rebuild['active_layout']] = ot_encode( serialize( get_option( ot_options_id() ) ) ); } $first_layout = ''; @@ -1893,12 +2246,12 @@ /* execute the action hook and pass the theme options to it */ do_action( 'ot_before_theme_options_save', $rebuild_option_tree ); - update_option( 'option_tree', $rebuild_option_tree ); + update_option( ot_options_id(), $rebuild_option_tree ); } /* rebuild the layouts */ - update_option( 'option_tree_layouts', $rebuild ); + update_option( ot_layouts_id(), $rebuild ); /* change message */ $message = 'success'; @@ -1906,7 +2259,7 @@ } else if ( count( $rebuild ) <= 1 ) { /* delete layouts option */ - delete_option( 'option_tree_layouts' ); + delete_option( ot_layouts_id() ); /* change message */ $message = 'deleted'; @@ -1915,9 +2268,9 @@ /* redirect */ if ( isset( $_REQUEST['page'] ) && $_REQUEST['page'] == apply_filters( 'ot_theme_options_menu_slug', 'ot-theme-options' ) ) { - $query_args = add_query_arg( array( 'settings-updated' => 'layout' ), remove_query_arg( array( 'action', 'message' ), $_POST['_wp_http_referer'] ) ); + $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 = add_query_arg( array( 'action' => 'save-layouts', 'message' => $message ), $_POST['_wp_http_referer'] ); + $query_args = esc_url_raw( add_query_arg( array( 'action' => 'save-layouts', 'message' => $message ), $_POST['_wp_http_referer'] ) ); } wp_redirect( $query_args ); exit; @@ -1946,6 +2299,12 @@ 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'] : ''; @@ -2023,7 +2382,7 @@ } - do_action( 'ot_custom_page_messages' ); + do_action( 'ot_custom_page_messages', $page ); if ( $updated == 'true' ) { @@ -2054,37 +2413,51 @@ function ot_option_types_array() { return apply_filters( 'ot_option_types_array', array( - 'background' => 'Background', - 'category-checkbox' => 'Category Checkbox', - 'category-select' => 'Category Select', - 'checkbox' => 'Checkbox', - 'colorpicker' => 'Colorpicker', - 'css' => 'CSS', - 'custom-post-type-checkbox' => 'Custom Post Type Checkbox', - 'custom-post-type-select' => 'Custom Post Type Select', - 'list-item' => 'List Item', - 'measurement' => 'Measurement', - 'numeric-slider' => 'Numeric Slider', - 'page-checkbox' => 'Page Checkbox', - 'page-select' => 'Page Select', - 'post-checkbox' => 'Post Checkbox', - 'post-select' => 'Post Select', - 'radio' => 'Radio', - 'radio-image' => 'Radio Image', - 'select' => 'Select', - 'sidebar-select' => 'Sidebar Select', - 'slider' => 'Slider', - 'tag-checkbox' => 'Tag Checkbox', - 'tag-select' => 'Tag Select', - 'taxonomy-checkbox' => 'Taxonomy Checkbox', - 'taxonomy-select' => 'Taxonomy Select', - 'text' => 'Text', - 'textarea' => 'Textarea', - 'textarea-simple' => 'Textarea Simple', - 'textblock' => 'Textblock', - 'textblock-titled' => 'Textblock Titled', - 'typography' => 'Typography', - 'upload' => 'Upload' + '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') ) ); } @@ -2142,6 +2515,38 @@ } /** + * 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; +} +add_filter( 'ot_recognized_font_families', 'ot_google_font_stack', 1, 2 ); + +/** * Recognized font families * * Returns an array of all recognized font families. @@ -2160,8 +2565,8 @@ if ( ! function_exists( 'ot_recognized_font_families' ) ) { function ot_recognized_font_families( $field_id = '' ) { - - return apply_filters( 'ot_recognized_font_families', array( + + $families = array( 'arial' => 'Arial', 'georgia' => 'Georgia', 'helvetica' => 'Helvetica', @@ -2170,7 +2575,9 @@ 'times' => '"Times New Roman", sans-serif', 'trebuchet' => 'Trebuchet', 'verdana' => 'Verdana' - ), $field_id ); + ); + + return apply_filters( 'ot_recognized_font_families', $families, $field_id ); } @@ -2205,7 +2612,7 @@ $range[$k] = $v . $unit; } - return $range; + return apply_filters( 'ot_recognized_font_sizes', $range, $field_id ); } } @@ -2335,7 +2742,7 @@ $range[$k] = $v . $unit; } - return $range; + return apply_filters( 'ot_recognized_letter_spacing', $range, $field_id ); } } @@ -2360,7 +2767,7 @@ $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_unit_type', 1, $field_id ) + apply_filters( 'ot_line_height_range_interval', 1, $field_id ) ); $unit = apply_filters( 'ot_line_height_unit_type', 'px', $field_id ); @@ -2369,7 +2776,7 @@ $range[$k] = $v . $unit; } - return $range; + return apply_filters( 'ot_recognized_line_heights', $range, $field_id ); } } @@ -2528,6 +2935,214 @@ } /** + * 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 ); + + } + +} + +/** + * 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 ); + + } + +} + +/** + * 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_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 ); + + } + +} + +/** + * 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 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 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 ); + + } + +} + +/** * Measurement Units * * Returns an array of all available unit types. @@ -2749,6 +3364,53 @@ } /** + * 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; + + } + +} + +/** * Inserts CSS with field_id markers. * * Inserts CSS into a dynamic.css file, placing it between @@ -2761,83 +3423,163 @@ * * @access public * @since 1.1.8 - * @updated 2.0.12 + * @updated 2.5.3 */ 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 */ - update_option( 'ot_css_file_paths', $ot_css_file_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_id = str_replace( array( '{{', '}}' ), '', $option ); - $option_array = explode( '|', $option_id ); - - /* get the array 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_array[0], true ); - + + $value = get_post_meta( $post->ID, $option_id, true ); + + // Get the options array value } else { - - $options = get_option( 'option_tree' ); - - if ( isset( $options[$option_array[0]] ) ) { - - $value = $options[$option_array[0]]; - + + $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 ( ! isset( $option_array[1] ) ) { - - /* Measurement */ - if ( isset( $value[0] ) && isset( $value[1] ) ) { - - /* set $value with measurement properties */ - $value = $value[0].$value[1]; - - /* typography */ - } else if ( ot_array_keys_exists( $value, array( 'font-color', 'font-family', 'font-size', 'font-style', 'font-variant', 'font-weight', 'letter-spacing', 'line-height', 'text-decoration', 'text-transform' ) ) ) { + + 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'] ) { @@ -2845,102 +3587,205 @@ } } } - + 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 */ + + // Set $value with font properties or empty string $value = ! empty( $font ) ? implode( "\n", $font ) : ''; - - /* background */ - } else if ( ot_array_keys_exists( $value, array( 'background-color', 'background-image', 'background-repeat', 'background-attachment', 'background-position' ) ) ) { + + // Background + } else if ( $option_type == 'background' ) { $bg = array(); - + if ( ! empty( $value['background-color'] ) ) $bg[] = $value['background-color']; - - if ( ! empty( $value['background-image'] ) ) + + 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']; - - /* set $value with background properties or empty string */ + + 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_array[1]]; - + + $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 ) ); - + $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 ) ); + } - - /* create array from the lines of code */ + + // 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' ) ) + + // 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 */ + + // Has array of lines if ( ! empty( $markerdata ) ) { - - /* foreach line of code */ + + // Foreach line of code foreach( $markerdata as $n => $markerline ) { - - /* found begining of marker, set $searching to false */ + + // Found begining of marker, set $searching to false if ( $markerline == "/* BEGIN {$marker} */" ) $searching = false; - - /* keep rewrite each line of CSS */ + + // 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 */ + + // Found end marker write code if ( $markerline == "/* END {$marker} */" ) { ot_file_write( $f, "/* BEGIN {$marker} */\n" ); ot_file_write( $f, "{$insertion}\n" ); @@ -2948,23 +3793,23 @@ $searching = true; $foundit = true; } - + } - + } - - /* nothing inserted, write code. DO IT, DO IT! */ + + // 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 */ + + // Close file ot_file_close( $f ); return true; } - + return false; } @@ -3122,7 +3967,7 @@ $content = ''; - foreach( $choices as $key => $choice ) + foreach( (array) $choices as $key => $choice ) $content.= '
  • ' . ot_choices_view( $name, $key, $choice ) . '
  • '; return $content; @@ -3177,11 +4022,11 @@
    ' . ( isset( $section['title'] ) ? esc_attr( $section['title'] ) : 'Section ' . ( $key + 1 ) ) . '
    - - ' . __( 'Edit', 'option-tree' ) . ' + + ' . __( 'Edit', 'option-tree' ) . ' - - ' . __( 'Delete', 'option-tree' ) . ' + + ' . __( 'Delete', 'option-tree' ) . '
    @@ -3229,13 +4074,14 @@ $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( 'textarea', 'textarea-simple', 'css' ) ) ) { + if ( in_array( $type, array( 'css', 'javascript', 'textarea', 'textarea-simple' ) ) ) { $std_form_element = ''; } else { $std_form_element = ''; @@ -3245,11 +4091,11 @@
    ' . ( isset( $setting['label'] ) ? esc_attr( $setting['label'] ) : 'Setting ' . ( $key + 1 ) ) . '
    @@ -3295,7 +4141,7 @@
      ' . ( isset( $setting['choices'] ) ? ot_loop_through_choices( $name . '[' . $key . ']', $setting['choices'] ) : '' ) . '
    - ' . __( 'Add Choice', 'option-tree' ) . ' + ' . __( 'Add Choice', 'option-tree' ) . '
    @@ -3306,7 +4152,7 @@ - ' . __( 'Add Setting', 'option-tree' ) . ' + ' . __( 'Add Setting', 'option-tree' ) . '
    @@ -3358,6 +4204,25 @@ +
    +
    +
    ' . 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 ? '' : '' ); @@ -3389,11 +4254,11 @@
    ' . ( isset( $choice['label'] ) ? esc_attr( $choice['label'] ) : 'Choice ' . ( $key + 1 ) ) . '
    - - ' . __( 'Edit', 'option-tree' ) . ' + + ' . __( 'Edit', 'option-tree' ) . ' - - ' . __( 'Delete', 'option-tree' ) . ' + + ' . __( 'Delete', 'option-tree' ) . '
    @@ -3455,11 +4320,11 @@
    ' . ( isset( $content['title'] ) ? esc_attr( $content['title'] ) : 'Content ' . ( $key + 1 ) ) . '
    @@ -3506,22 +4371,22 @@ * @access public * @since 2.0 */ -if ( ! function_exists( 'ot_layouts_view' ) ) { +if ( ! function_exists( 'ot_layout_view' ) ) { function ot_layout_view( $key, $data = '', $active_layout = '' ) { - + return ' '; } @@ -3583,11 +4448,164 @@
    ' . ( 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 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'] ) : '' ) . '
    +
    '; @@ -3618,38 +4636,59 @@ '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 '
    '; + echo '
    '; + + /* don't show title with textblocks */ + if ( $_args['type'] != 'textblock' && ! empty( $field['label'] ) ) { + echo '
    '; + echo '

    ' . esc_attr( $field['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'; + /* 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' ) { - echo ot_display_by_type( $_args ); - } + /* 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 '
    '; + + echo '
    '; } @@ -3673,7 +4712,7 @@ wp_nonce_field( 'option_tree_modify_layouts_form', 'option_tree_modify_layouts_nonce' ); /* get the saved layouts */ - $layouts = get_option( 'option_tree_layouts' ); + $layouts = get_option( ot_layouts_id() ); /* set active layout */ $active_layout = isset( $layouts['active_layout'] ) ? $layouts['active_layout'] : ''; @@ -3686,7 +4725,7 @@ echo '
    '; - echo ''; foreach( $layouts as $key => $data ) { @@ -3705,7 +4744,7 @@ if ( $key == 'active_layout' ) continue; - echo ''; + echo ''; } @@ -3715,9 +4754,9 @@ echo '
    '; /* add new layout */ - echo ''; + echo ''; - echo ''; + echo ''; echo '
    '; @@ -4105,6 +5144,178 @@ } /** + * 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 ); + +} + +/** + * 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 ); + +} +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; + +} + +/** + * 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; + +} + +/** * Helper function to register a WPML string * * @access public @@ -4136,5 +5347,777 @@ } +/** + * 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 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 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 ); + + } + + } + +} + +/** + * 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 ); + +} + +/** + * 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 ); + +} + +/** + * 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 ); + +} + +/** + * 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 ); + +} + +/** + * 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 ); + +} + +/** + * 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; + + } + +} + +/** + * 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; + +} + +/** + * 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; + +} + +/** + * 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 ); + + } + + } + + } + + } + + } + + } + + } + +} +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