nstance->set_items( $items ); $out = $feg_instance->get_fields( false, false ); } else { $out = call_user_func( $fields[ $section_id ]['ajax-section-handler'], $args ); } } wp_send_json( compact( 'out', 'section_id' ) ); } /** * Callback: Used for adding page custom classes to admin body * * @param $classes * * @since 2.0 * * @return string */ function admin_body_class( $classes ) { if ( ! $this->get_current_page_id() ) { return $classes; } $classes = explode( ' ', $classes ); $classes = array_flip( $classes ); $classes['bf-admin-panel'] = 'bf-admin-panel'; $classes['hide-notices'] = 'hide-notices'; return implode( ' ', $classes ); } /** * Hook register menus to WordPress * * @since 1.0 * @access public * @return void */ public function add_menu() { if ( ! is_admin() || bf_is_doing_ajax() ) { return; } foreach ( BF_Options::$panels as $panel_id => $panel ) { $config = BF_Options::load_panel_config( $panel_id ); if ( ! isset( $config['config'] ) ) { continue; } $menu = $config['config']; $menu['id'] = $panel_id; if ( isset( $panel['theme-panel'] ) ) { $menu['theme-panel'] = true; } // prepare slug if ( ! isset( $menu['callback'] ) ) { $menu['callback'] = array( $this, 'menu_callback' ); } Better_Framework()->admin_menus()->add_menupage( $menu ); } } /** * Get All Paths * * get all paths, such as template directories * * @since 1.0 * @access public * @return array|bool */ public function get_all_paths() { $id = $this->get_current_page_id(); if ( $id == false ) { return false; } $i = BF_PATH . '/includes/'; $custom_template = apply_filters( "better-framework/admin-panel/template/{$id}", '' ); $output = array(); $output['custom-panel-main-default-template'] = $i . 'templates/admin-panel/default/'; $output['custom-panel-main-template-current-page'] = $custom_template; $output['default-panel-main-template'] = bf_get_dir( "admin-panel/templates/default/" ); return $output; } /** * Get current page * * Return current page id * * static * * @since 1.0 * @access public * @return string */ public function get_current_page_id() { if ( ! isset( $_GET['page'] ) ) { return false; } $page = explode( '/', $_GET['page'] ); if ( empty( $page[1] ) ) { return false; } switch ( $page[1] ) { // Support better-translation slug case 'translations': return $page[2]; default: // Validating panel id by slug. if ( $this->get_page_data_by_id( $page[1] ) ) { return $page[1]; } return false; } } /** * Get page data which is hooked to better-framework/panel/options * * @param string $panel_id Needed page ID * * @since 1.0 * @access public * @return bool|array */ public function get_page_data_by_id( $panel_id ) { // If panel slug is page id if ( isset( BF_Options::$panels[ $panel_id ] ) ) { return BF_Options::load_panel_config( $panel_id ); } // Check for panels with custom slug else { foreach ( BF_Options::$panels as $_panel_id => $panel ) { $panel = BF_Options::load_panel_config( $_panel_id ); if ( isset( $panel['config']['slug'] ) && ( $panel['config']['slug'] == $panel_id || $panel['config']['slug'] == ( 'better-studio/' . $panel_id ) || $panel['config']['slug'] == ( 'better-studio/translations/' . $panel_id ) ) ) { $panel['panel-id'] = $_panel_id; return $panel; } } } return false; } /** * Get page current data * * @since 1.0 * @access public * @return bool|array */ public function get_current_page_data() { return $this->get_page_data_by_id( $this->get_current_page_id() ); } /** * Menu Callback * * The callback of add_menupage which is about the front-end stuff * * todo add support for custom template for each panel * * @since 1.0 * @access public * @return mixed */ public function menu_callback() { $id = $this->get_current_page_id(); // If panel id is not valid. if ( ! $id ) { return; } $data = (array) $this->get_current_page_data(); // Update panel id, this used because of custom slug for pages if ( isset( $data['panel-id'] ) ) { $id = $data['panel-id']; } if ( ! class_exists( 'BF_Admin_Panel_Front_End_Generator' ) ) { require BF_PATH . 'admin-panel/class-bf-admin-panel-front-end-generator.php'; } $front_end_instance = new BF_Admin_Panel_Front_End_Generator( $data, $id ); // Defined Template Tags $this->template = array( 'id' => $id, 'data' => $data, 'tabs' => $front_end_instance->get_tabs(), 'fields' => $front_end_instance->get_fields(), 'texts' => array( // Reset Buttons 'reset-button' => isset( $data['texts']['reset-button'] ) ? $data['texts']['reset-button'] : __( 'Reset Settings', 'publisher' ), 'reset-button-all' => isset( $data['texts']['reset-button-all'] ) ? $data['texts']['reset-button-all'] : __( 'Reset All Settings', 'publisher' ), // Reset Confirms 'reset-confirm' => isset( $data['texts']['reset-confirm'] ) ? $data['texts']['reset-confirm'] : __( 'Are you sure to reset settings?', 'publisher' ), 'reset-confirm-all' => isset( $data['texts']['reset-confirm-all'] ) ? $data['texts']['reset-confirm-all'] : __( 'Are you sure to reset all settings?', 'publisher' ), // Save Buttons 'save-button' => isset( $data['texts']['save-button'] ) ? $data['texts']['save-button'] : __( 'Save Settings', 'publisher' ), 'save-button-all' => isset( $data['texts']['save-button-all'] ) ? $data['texts']['save-button-all'] : __( 'Save All Settings', 'publisher' ), // Save Confirms 'save-confirm' => isset( $data['texts']['save-confirm'] ) ? $data['texts']['save-confirm'] : '', 'save-confirm-all' => isset( $data['texts']['save-confirm-all'] ) ? $data['texts']['save-confirm-all'] : __( 'Are you sure to save all settings? this will override specified settings per languages', 'publisher' ), ) ); // Add tab class $has_tab = $front_end_instance->has_tab(); if ( $has_tab ) { $this->template['css-class'][] = 'panel-with-tab'; } else { $this->template['css-class'][] = 'panel-without-tab'; } if ( isset( $data['panel-desc'] ) ) { $this->template['desc'] = $data['panel-desc']; } $lang = bf_get_current_lang_raw(); if ( $lang != 'none' ) { if ( $lang == 'all' && isset( $data['texts']['panel-desc-lang-all'] ) ) { $this->template['desc'] = $data['texts']['panel-desc-lang-all']; } elseif ( isset( $data['texts']['panel-desc-lang'] ) ) { $this->template['desc'] = sprintf( $data['texts']['panel-desc-lang'], bf_get_language_name( $lang ) ); } } $paths = $this->get_all_paths(); if ( file_exists( $paths['custom-panel-main-template-current-page'] . 'main.php' ) ) { require_once $paths['custom-panel-main-template-current-page'] . 'main.php'; } elseif ( file_exists( $paths['custom-panel-main-default-template'] . 'main.php' ) ) { require_once $paths['custom-panel-main-default-template'] . 'main.php'; } else { require_once $paths['default-panel-main-template'] . 'main.php'; } } /** * Handle Save Options * * @param array $args The variable that includes all options in array * * @since 1.0 * @return void */ public function handle_saving_option_panel( $args ) { /** * Fires before options save * * @param string $args arguments * * @since 2.0 * */ do_action( 'better-framework/panel/save/before', $args ); if ( ! isset( $args['lang'] ) ) { $args['lang'] = ''; } if ( $args['lang'] != 'all' ) { // Prepare Language if ( is_null( $args['lang'] ) || $args['lang'] == 'en' || $args['lang'] == 'none' ) { $lang_full = ''; } else { $lang_full = '_' . $args['lang']; } // Fix for magic_quotes_gpc if ( function_exists( 'get_magic_quotes_gpc' ) && is_callable( 'get_magic_quotes_gpc' ) && @get_magic_quotes_gpc() ) { $args['data'] = stripslashes_deep( $args['data'] ); } // init value if not before if ( ! isset( BF_Options::$values[ $args['id'] ] ) ) { BF_Options::$values[ $args['id'] ] = get_option( $args['id'] . $lang_full ); } // combine values foreach ( (array) $args['data'] as $field_id => $field_value ) { BF_Options::$values[ $args['id'] ][ $field_id ] = $field_value; } $skin_state = $this->prepare_skin( $args['id'], BF_Options::$values[ $args['id'] ], $args['lang'] ); if ( Better_Framework()->options()->add_option( $args['id'], BF_Options::$values[ $args['id'] ], $args['lang'] ) !== false ) { Better_Framework()->factory( 'custom-css-fe' )->clear_cache( 'all' ); $output = array( 'status' => 'succeed', 'msg' => __( 'Options saved.', 'publisher' ), 'notice' => $skin_state ? __( 'Pre-defined Skin and Styles updated.', 'publisher' ) : __( 'All options saved.', 'publisher' ), 'refresh' => $skin_state, ); } else { $output = array( 'status' => 'error', 'msg' => __( 'Error happened in saving option.', 'publisher' ) ); } } else { foreach ( bf_get_all_languages() as $lang ) { if ( $lang['id'] == 'en' ) { $_lang = 'none'; } else { $_lang = $lang['id']; } // Prepare Language if ( is_null( $lang['id'] ) || $lang['id'] == 'en' || $lang['id'] == 'none' ) { $lang_full = ''; } else { $lang_full = '_' . $lang['id']; } // Fix for magic_quotes_gpc if ( function_exists( 'get_magic_quotes_gpc' ) && is_callable( 'get_magic_quotes_gpc' ) && @get_magic_quotes_gpc() ) { $args['data'] = stripslashes_deep( $args['data'] ); } // init value if not before if ( ! isset( BF_Options::$values[ $args['id'] . $lang_full ] ) ) { $saved_before = get_option( $args['id'] . $lang_full ); if ( $saved_before == false ) { $saved_before = get_option( $args['id'] ); } BF_Options::$values[ $args['id'] . $lang_full ] = $saved_before; } // combine values foreach ( (array) $args['data'] as $field_id => $field_value ) { BF_Options::$values[ $args['id'] . $lang_full ][ $field_id ] = $field_value; } $skin_state = $this->prepare_skin( $args['id'], BF_Options::$values[ $args['id'] . $lang_full ], $_lang ); if ( Better_Framework()->options()->add_option( $args['id'], BF_Options::$values[ $args['id'] . $lang_full ], $_lang ) !== false ) { Better_Framework()->factory( 'custom-css-fe' )->clear_cache( 'all' ); $output = array( 'status' => 'succeed', 'msg' => __( 'Options saved.', 'publisher' ), 'notice' => $skin_state ? __( 'Pre-defined Skin and Styles updated.', 'publisher' ) : __( 'All options saved.', 'publisher' ), 'refresh' => $skin_state, ); } else { $output = array( 'status' => 'error', 'msg' => __( 'Error happened in saving option.', 'publisher' ) ); } } } /** * Filter result of save panel * * @param array $output contains result of save * @param string $options contain options * * @since 2.0 * */ $output = apply_filters( 'better-framework/panel/save/result', $output, $args ); if ( $skin_state && ( $output['status'] == 'succeed' ) ) { Better_Framework()->admin_notices()->add_notice( array( 'msg' => $output['notice'] ) ); } /** * Fires after panel save * * @param string $args contain options * @param array $output arguments * * @since 2.0 * */ do_action( 'better-framework/panel/reset/after', $output, $args ); echo json_encode( $output ); } /** * Prepare values of options before save for specified values for styles. * * Checks if "style" was changed then check all fields for custom value for new style and change them and returns * changed option. * * @param string $panel_id Panel ID * @param array $data Panel Data * @param null $lang Panel Language * * @return bool */ function prepare_skin( $panel_id, &$data = array(), $lang = null ) { BF_Options::get_panels(); // if panel have not valid or have not style if ( ! isset( BF_Options::$panels[ $panel_id ] ) || ! isset( BF_Options::$panels[ $panel_id ]['style'] ) || ! BF_Options::$panels[ $panel_id ]['style'] ) { return false; } // if data is empty or not added to function if ( bf_count( $data ) <= 0 ) { return false; } if ( is_null( $lang ) || empty( $lang ) ) { $lang = bf_get_current_lang(); } if ( $lang == 'en' || $lang == 'none' || $lang == 'all' ) { $_lang = ''; } else { $_lang = '_' . $lang; } $current_style = get_option( $panel_id . $_lang . '_current_style' ); // if skin not changed if ( $current_style == $data['style'] ) { return false; } // update style update_option( $panel_id . $_lang . '_current_style', $data['style'], ! empty( $_lang ) ? 'no' : 'yes' ); // Panel all default values $default = BF_Options::get_panel_std( $panel_id ); // Panel all fields $fields = BF_Options::load_panel_fields( $panel_id ); // Panel std id if ( $data['style'] == bf_get_panel_default_style() ) { $std_id = 'std'; } else { $std_id = 'std-' . $data['style']; } foreach ( (array) $fields as $field ) { // no style // not in this style if ( ! isset( $field['style'] ) || ! in_array( $current_style, $field['style'] ) ) { continue; } // If field have std value then change current value std std value if ( isset( $default[ $field['id'] ][ $std_id ] ) ) { $data[ $field['id'] ] = $default[ $field['id'] ][ $std_id ]; } elseif ( isset( $default[ $field['id'] ]['std'] ) ) { $data[ $field['id'] ] = $default[ $field['id'] ]['std']; } } return true; } /** * Reset All Options * * @param $data * * @since 1.0 * * @return void */ public function reset_options( $data ) { /** * Fires before options reset * * @param string $data contain options * * @since 2.0 * */ do_action( 'better-framework/panel/reset/before', $data ); $fields = BF_Options::load_panel_fields( $data['id'] ); // Reset specific language panel data if ( $data['lang'] != 'all' ) { if ( isset( $fields['style'] ) ) { if ( $data['lang'] != 'none' && ! empty( $data['lang'] ) ) { update_option( $data['id'] . '_' . $data['lang'] . '_current_style', 'default' ); } else { update_option( $data['id'] . '_current_style', bf_get_panel_default_style( $data['id'] ) ); } } if ( Better_Framework::options()->save_panel_default_values( $data['id'], $data['lang'] ) !== false ) { Better_Framework::factory( 'custom-css-fe' )->clear_cache( 'all' ); $result = array( 'status' => 'succeed', 'msg' => __( 'Options Reset to default.', 'publisher' ), 'refresh' => true, ); } else { $result = array( 'status' => 'error', 'msg' => __( 'An error occurred while resetting options.', 'publisher' ) ); } } // Reset panel data for all languages else { foreach ( bf_get_all_languages() as $lang ) { if ( $lang['language_code'] == 'en' ) { $_lang = 'none'; } else { $_lang = $lang['language_code']; } if ( isset( $fields['style'] ) ) { if ( $data['lang'] != 'none' && ! empty( $data['lang'] ) ) { update_option( $data['id'] . '_' . $_lang . '_current_style', 'default' ); } else { update_option( $data['id'] . '_current_style', 'default' ); } } if ( Better_Framework::options()->save_panel_default_values( $data['id'], $_lang ) !== false ) { Better_Framework::factory( 'custom-css-fe' )->clear_cache( 'all' ); $result = array( 'status' => 'succeed', 'msg' => __( 'Options Reset to default.', 'publisher' ), 'refresh' => true, ); } else { $result = array( 'status' => 'error', 'msg' => __( 'An error occurred while resetting options.', 'publisher' ) ); } } } /** * Filter result of resetting panel * * @param array $result contains result of reset * @param string $data contain options * * @since 1.4.0 * */ $result = apply_filters( 'better-framework/panel/reset/result', $result, $data ); /** * Fires after options reset * * @param string $data contain options * @param array $result contains result of reset * * @since 2.0 * */ do_action( 'better-framework/panel/reset/after', $data, $result ); // Print result echo json_encode( $result ); Better_Framework::admin_notices()->add_notice( array( 'msg' => $result['msg'] ) ); } /** * Handle Ajax Import * * @param $file * @param $args * * @since 1.0 * * @return void */ public function handle_ajax_import( $file, $args ) { $data = bf_get_local_file_content( $file['tmp_name'] ); $data = json_decode( $data, true ); /** * Fires before options import * * @param string $data contain import file data * * @since 2.0 * */ do_action( 'better-framework/panel/import/before', $data ); // data is not correct if ( $data === false || ! isset( $data['panel-id'] ) || empty( $data['panel-id'] ) || ! isset( $data['panel-data'] ) || empty( $data['panel-data'] ) || ! isset( $args['panel-id'] ) || empty( $args['panel-id'] ) ) { $result = array( 'msg' => __( 'Imported data is not correct or was corrupted.', 'publisher' ), 'status' => 'error' ); } elseif ( $args['panel-id'] != $data['panel-id'] ) { $result = array( 'msg' => __( 'Imported data is not for this panel.', 'publisher' ), 'status' => 'error' ); } else { if ( isset( $args['lang'] ) && $args['lang'] != 'none' ) { $lang = $args['lang']; } else { $lang = ''; } // Save options update_option( $data['panel-id'] . ( empty( $lang ) ? '' : '_' . $lang ), $data['panel-data'] ); // Imports style if ( isset( $data['panel-data']['style'] ) && ! empty( $data['panel-data']['style'] ) ) { update_option( $data['panel-id'] . ( empty( $lang ) ? '' : '_' . $lang ) . '_current_style', $data['panel-data']['style'] ); } // Clear CSS caches Better_Framework::factory( 'custom-css-fe' )->clear_cache( 'all' ); $result = array( 'msg' => __( 'Theme Options successfully imported.', 'publisher' ), 'status' => 'succeed', 'refresh' => true, ); } /** * Filter result of import options * * @param string $data contains file data * @param array $result contains result of reset * @param array $args arguments * * @since 2.0 * */ $result = apply_filters( 'better-framework/panel/import/result', $result, $data, $args ); /** * Fires after options import * * @param string $data contains file data * @param array $result contains result of reset * * @since 2.0 * */ do_action( 'better-framework/panel/import/after', $data, $result ); // Print result echo json_encode( $result ); // Success notice if ( $result['status'] == 'succeed' ) { Better_Framework::admin_notices()->add_notice( array( 'msg' => $result['msg'], 'product' ) ); } } /** * @param string $panel_id * @param string $lang * * @return array|bool array on success or false on failure. */ public function get_export_data( $panel_id, $lang = 'none' ) { $export = array(); $panel_id = sanitize_key( $panel_id ); // validate panel id $config = apply_filters( "better-framework/panel/$panel_id/config", array() ); if ( empty( $config ) ) { return false; } $export['panel-id'] = $panel_id; $lang = $export['panel-multilingual'] = sanitize_key( $lang ); if ( $lang != 'none' ) { $lang = '_' . $lang; } else { $lang = ''; } $export['panel-data'] = get_option( $panel_id . $lang ); /** * Filter for export data * * @param string $options contains export data * * @since 2.0 * */ return apply_filters( 'better-framework/panel/export/data', $export ); } /** * Add Default Options After Theme Activated. * * @since 1.0 * @return void */ public function handle_export_download() { if ( ! is_user_logged_in() ) { die( "Illegal access." ); } if ( empty( $_POST['panel_id'] ) ) { return; } $panel_id = sanitize_key( $_POST['panel_id'] ); $lang = isset( $_POST['lang'] ) ? sanitize_key( $_POST['lang'] ) : ''; // Get panel capability $cap = empty( $config['config']['capability'] ) ? 'manage_options' : $config['config']['capability']; if ( ! current_user_can( $cap ) ) { die( "Illegal access." ); } $options_array = $this->get_export_data( $panel_id, $lang ); /** * Fires before options export * * @param string $options contains export data * * @since 2.0 * */ do_action( 'better-framework/panel/export/before', $options_array ); // Custom file name for each theme if ( isset( $_POST['file_name'] ) && ! empty( $_POST['file_name'] ) ) { $file_name = $_POST['file_name'] . '-' . date( 'm-d-Y h:i:s a', time() ); } else { $file_name = 'options-backup-' . date( 'm-d-Y h:i:s a', time() ); } /** * Filter export file name * * @param string $filename contains current file name * @param string $options contains export data * * @since 2.0 * */ $file_name = apply_filters( 'better-framework/panel/export/file-name', sanitize_file_name( $file_name ), $options_array ); $options_array = json_encode( $options_array ); // No Cache header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' ); header( 'Cache-Control: no-store, no-cache, must-revalidate' ); header( 'Cache-Control: post-check=0, pre-check=0', false ); header( 'Pragma: no-cache' ); header( 'Content-Type: application/force-download' ); header( 'Content-Length: ' . strlen( $options_array ) ); header( 'Content-Disposition: attachment; filename="' . $file_name . '.json"' ); add_filter( 'wp_die_handler', array( $this, 'wp_die_handler' ) ); wp_die( $options_array ); } /** * @hooked wp_die_handler in handle_export_download method * * @return array */ public function wp_die_handler() { return array( $this, 'print_and_exit' ); } /** * @param string $data */ public function print_and_exit( $data ) { echo $data; exit; } }