lback_panel_reset_result' ), 10, 2 ); // Callback for importing data add_filter( 'better-framework/panel/import/result', array( $this, 'callback_panel_import_result' ), 10, 3 ); // Callback for adding current language to export file add_filter( 'better-framework/panel/export/data', array( $this, 'callback_panel_export_data' ) ); // Callback for changing export file name add_filter( 'better-framework/panel/export/file-name', array( $this, 'callback_panel_export_file_name' ), 10, 2 ); // Callback changing save result add_filter( 'better-framework/panel/save/result', array( $this, 'callback_panel_save_result' ), 10, 2 ); // Admin style and scripts if ( is_admin() ) { add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); } unset( $config ); } /** * Callback: Init's BF options * * Filter: better-framework/panel/options * * @param $panels * * @return mixed */ public function panel_add( $panels ) { $panels[ $this->option_panel_id ] = array( 'id' => $this->option_panel_id, 'style' => false, 'css' => false, ); return $panels; } // panel_add /** * Callback: Init's BF options * * Filter: better-framework/panel/options * * @param $panel * * @return mixed */ public function panel_config( $panel ) { include $this->dir_path . 'panel-config.php'; return $panel; } // config_panel /** * Callback: Init's BF options * * Filter: better-framework/panel/options * * @param $fields * * @return mixed */ public function panel_fields( $fields ) { include $this->dir_path . 'panel-fields.php'; return $fields; } // panel_fields /** * Callback: Init's BF options * * Filter: better-framework/panel/options * * @param $fields * * @return mixed */ public function panel_std( $fields ) { include $this->dir_path . 'panel-std.php'; return $fields; } // panel_std /** * Used for accessing alive instance of Publisher_Translation * * @since 1.0 * * @return Publisher_Translation */ public static function self() { return self::factory( 'self' ); } /** * Build the required object instance * * @param string $object * @param bool $fresh * @param bool $just_include * * @return null|Publisher_Translation */ public static function factory( $object = 'self', $fresh = false, $just_include = false ) { if ( isset( self::$instances[ $object ] ) && ! $fresh ) { return self::$instances[ $object ]; } switch ( $object ) { /** * Main Publisher_Translation Class */ case 'self': $class = 'Publisher_Translation'; break; default: return null; } // Just prepare/includes files if ( $just_include ) { return; } // don't cache fresh objects if ( $fresh ) { return new $class; } self::$instances[ $object ] = new $class; return self::$instances[ $object ]; } /** * Used for retrieving Publisher Translation version * * @return string */ function get_version() { return $this->version; } /** * Used for retrieving Publisher Translation directory URL * * @return string */ function get_dir_url() { return $this->dir_url; } /** * Used for retrieving Publisher Translation directory path * * @return string */ function get_dir_path() { return $this->dir_path; } /** * Used for retrieving current language ( active ) * * @return string */ function get_current_lang() { $multilingual = bf_get_current_language_option_code(); if ( ( $current = get_option( $this->option_panel_id . $multilingual . '-current' ) ) == true ) { return $current; } else { return false; } } /** * Used for saving current language ( active ) * * @param $lang * @param null $multilingual */ function set_current_lang( $lang, $multilingual = null ) { if ( is_null( $multilingual ) ) { $multilingual = bf_get_current_lang(); } if ( $multilingual == 'en' || $multilingual == 'none' || empty( $multilingual ) || $multilingual == 'all' ) { $multilingual = ''; } else { $multilingual = '_' . $multilingual; } update_option( $this->option_panel_id . $multilingual . '-current', $lang ); } /** * Used for retrieving pre translations * * @return array */ function get_languages() { static $loaded; if ( $loaded ) { return $this->languages; } $loaded = true; return $this->languages = apply_filters( 'publisher-theme-core/translation/languages', array() ); } /** * Used for retrieving a translation from panel * * Use like __() function * * todo add default value for this function * * @param $option_key * * @return mixed|null */ function _get( $option_key ) { return bf_get_option( $option_key, $this->option_panel_id ); } /** * Used for retrieving a translation from panel * * Use like esc_attr__() function * * @param $option_key * * @return mixed|null */ function _get_esc_attr( $option_key ) { return esc_attr( bf_get_option( $option_key, $this->option_panel_id ) ); } /** * Used for retrieving a translation from panel * * Use like _e() function * * @param $option_key * * @return mixed|null */ function _echo( $option_key ) { bf_echo_option( $option_key, $this->option_panel_id ); } /** * Used for retrieving a translation from panel * * Use like esc_attr__() function * * @param $option_key * * @return mixed|null */ function _echo_esc_attr( $option_key ) { echo esc_attr( bf_get_option( $option_key, $this->option_panel_id ) ); } /** * Enqueue scripts and styles */ function enqueue_scripts() { include $this->dir_path . 'scripts.php'; } /** * Callback for changing translations * * @param string $lang Selected Language ID * @param null|string $current_lang Current WP Language ( Multilingual ) * * @return array */ public static function change_translation( $lang, $current_lang = null ) { if ( $current_lang === 'en_US' || $current_lang === 'none' || empty( $current_lang ) ) { $_multilingual = ''; } else { $_multilingual = '_' . $current_lang; } // Don't download file for "en_US" if ( $lang === 'en_US' ) { // empty panel -> data will be come from STD $panel_data = array( 'lang-id' => $lang ); update_option( publisher_translation()->option_panel_id . $_multilingual, $panel_data, ! empty( $_multilingual ) ? 'no' : 'yes' ); publisher_translation()->set_current_lang( $lang, $current_lang ); $result = array( 'status' => 'succeed', 'msg' => sprintf( __( 'Theme translation changed to "%s"', 'publisher' ), __( 'English - US', 'publisher' ) ), 'refresh' => true ); // Add admin notice Better_Framework()->admin_notices()->add_notice( array( 'msg' => $result['msg'], 'thumbnail' => publisher_translation()->notice_icon, 'product' => 'theme:publisher', ) ); return $result; } $languages = publisher_translation()->get_languages(); /** * Fires before changing translation * * @param string $lang Selected translation id for change * @param array $translations All active translations list * * @since 1.0.0 * */ do_action( 'publisher-theme-core/translation/change-translation/before', $lang, $languages ); $translation = self::get_language_translation( $lang ); if ( $translation['status'] === 'error' ) { $translation['refresh'] = false; return $translation; } /** * Filter translation data * * @since 1.0.0 */ $data = apply_filters( 'publisher-theme-core/translation/change-translation/data', $translation['translation'] ); // Validate translation file data if ( ! isset( $data['panel-id'] ) || empty( $data['panel-id'] ) || ! isset( $data['panel-data'] ) ) { return array( 'status' => 'error', 'msg' => __( 'Translation file for selected language is not valid!', 'publisher' ), 'refresh' => false ); } // Validate translation panel id if ( $data['panel-id'] !== publisher_translation()->option_panel_id ) { return array( 'status' => 'error', 'error_code' => 'invalid-translation', 'msg' => sprintf( __( 'Translation file is not valid for "%s"', 'publisher' ), publisher_translation()->publisher ), 'refresh' => false ); } // Save translation and update current lang update_option( publisher_translation()->option_panel_id . $_multilingual, $data['panel-data'], ! empty( $_multilingual ) ? 'no' : 'yes' ); publisher_translation()->set_current_lang( $lang, $current_lang ); $result = array( 'status' => 'succeed', 'msg' => sprintf( __( 'Theme translation changed to "%s"', 'publisher' ), $languages[ $lang ]['name'] ), 'refresh' => true ); // Add admin notice Better_Framework()->admin_notices()->add_notice( array( 'msg' => $result['msg'], 'thumbnail' => publisher_translation()->notice_icon, 'product' => 'theme:publisher', ) ); return $result; } /** * Callback for send translations * * @param string $lang_name * @param string $lang_code * @param string $translator * * @throws BF_Exception * @return array */ public static function callback_send_translation( $lang_name = '', $lang_code = '', $translator = '' ) { /** * Fires before send translation * * @param string $lang_name Language name * @param array $lang_code Country name * * @since 1.0.0 * */ do_action( 'publisher-theme-core/translation/send-translation/before', $lang_name, $lang_code ); $_current_user = wp_get_current_user(); $sent = BetterFramework_Oculus::request( 'share', array( 'group' => 'translation', 'data' => array( 'theme' => publisher_translation()->publisher, 'lang_name' => $lang_name, 'lang_code' => $lang_code, 'user_email' => $_current_user->user_email, 'translation' => json_encode( get_option( publisher_translation()->option_panel_id ) ), 'user_display_name' => $_current_user->data->display_name, ) ) ); if ( $sent ) { $result = array( 'status' => 'succeed', 'msg' => __( 'Translation sent successfully.', 'publisher' ), ); } else { $result = array( 'status' => 'error', 'msg' => __( 'There is a problem in sending translation.', 'publisher' ), ); } /** * Filter result of import options * * @param array $result contains result of reset * @param string $lang_name Language name * @param array $lang_code Country name * @param array $translator Translator name * @param array $desc Desc * * @since 1.0.0 * */ return apply_filters( 'publisher-theme-core/translation/send-translation/result', $result, $lang_name, $lang_code ); } /** * Filter callback: For changing email from name * * @param $name * * @return string */ function wp_mail_from_name( $name ) { $name = Publisher_Translation::$instances['from-name']; if ( empty( $name ) ) { $name = 'Anonymous'; } // remove cache unset( Publisher_Translation::$instances['from-name'] ); return $name; } /** * Filter callback: Used for resetting current language on resetting panel * * @param $options * @param $result * * @return array */ function callback_panel_reset_result( $result, $options ) { // check panel if ( $options['id'] != $this->option_panel_id ) { return $result; } // reset current language $this->set_current_lang( 'en_US' ); // change messages if ( $result['status'] == 'succeed' ) { $result['msg'] = __( 'Theme translation reset to default.', 'publisher' ); } else { $result['msg'] = __( 'An error occurred while resetting theme translation.', 'publisher' ); } return $result; } /** * Filter callback: Used for changing current language on importing translation panel data * * @param $result * @param $data * @param $args * * @return array */ function callback_panel_import_result( $result, $data, $args ) { // check panel if ( $args['panel-id'] != $this->option_panel_id ) { return $result; } // change messages if ( $result['status'] == 'succeed' ) { $result['msg'] = __( 'Theme translation successfully imported.', 'publisher' ); } else { if ( $result['msg'] == __( 'Imported data is not for this panel.', 'publisher' ) ) { $result['msg'] = __( 'Imported translation is not for this theme.', 'publisher' ); } else { $result['msg'] = __( 'An error occurred while importing theme translation.', 'publisher' ); } } // current lang if ( isset( $data['panel-data']['lang-id'] ) ) { $this->set_current_lang( $data['panel-data']['lang-id'] ); } else { $this->set_current_lang( 'en_US' ); } return $result; } /** * Filter callback: Used for adding current language to export data * * @param $options_array * * @return array */ function callback_panel_export_data( $options_array ) { if ( $options_array['panel-id'] == $this->option_panel_id ) { $options_array['panel-data']['lang-id'] = $this->get_current_lang(); } return $options_array; } /** * Filter callback: Used for changing export file name * * @param $file_name * @param $options_array * * @return string */ function callback_panel_export_file_name( $file_name, $options_array ) { // change only for translation panel if ( $options_array['panel-id'] == $this->option_panel_id ) { $file_name = $this->theme_id . '-' . $this->get_current_lang(); } return $file_name; } /** * Filter callback: Used for changing save translation panel result * * @param $output * @param $args * * @return string */ function callback_panel_save_result( $output, $args ) { // change only for translation panel if ( $args['id'] == $this->option_panel_id ) { if ( $output['status'] == 'succeed' ) { $output['msg'] = __( 'Translations saved.', 'publisher' ); } else { $output['msg'] = __( 'An error occurred while saving translations.', 'publisher' ); } } return $output; } /** * Callback: Used to add smart support of multilingual translation panel */ function setup_translation_panel_before() { // Get current multilingual language $multilingual = bf_get_current_lang(); // All languages page if ( $multilingual == 'all' ) { // Add current language to all languages foreach ( bf_get_all_languages() as $lang ) { if ( $lang['id'] == 'en' || $lang == 'all' ) { $_lang = ''; } else { $_lang = '_' . $lang['id']; } if ( false == get_option( $this->option_panel_id . $_lang . '-current' ) ) { $this->set_current_lang( 'en_US', $lang['id'] ); } } return; } elseif ( $multilingual == 'en' || $multilingual == 'none' || $multilingual == false ) { if ( false == get_option( $this->option_panel_id . '-current' ) ) { $this->set_current_lang( 'en_US' ); } return; } $_multilingual = '_' . $multilingual; $opt_current = get_option( $this->option_panel_id . $_multilingual . '-current' ); // if data is saved before if ( $opt_current !== false ) { return; } // Get language all information and locale $language = bf_get_language_data( $multilingual ); $languages = $this->get_languages(); // Use pre-translation if available if ( isset( $languages[ $language['locale'] ] ) ) { $translation_options_data = self::get_language_translation( $language['locale'] ); if ( $translation_options_data['status'] === 'error' ) { return; } /** * Filter translation data * * @since 1.0.0 */ $data = apply_filters( 'publisher-theme-core/translation/change-translation/data', $translation_options_data['translation'] ); // Validate translation file data if ( ! isset( $data['panel-id'] ) || empty( $data['panel-id'] ) || ! isset( $data['panel-data'] ) ) { return; } // Validate translation panel id if ( $data['panel-id'] != publisher_translation()->option_panel_id ) { return; } // Save translation and update current lang update_option( publisher_translation()->option_panel_id . $_multilingual, $data['panel-data'], ! empty( $_multilingual ) ? 'no' : 'yes' ); publisher_translation()->set_current_lang( $language['locale'], $multilingual ); } else { $this->set_current_lang( 'en_US', $multilingual ); } } /** * Handy function to get final translation data from locale (DRY) * * @param $lang_id * * @return array */ public static function get_language_translation( $lang_id ) { static $translation; // from cache (used for multilingual) if ( ! is_null( $translation ) && isset( $translation[ $lang_id ] ) ) { return $translation[ $lang_id ]; } $languages = publisher_translation()->get_languages(); if ( ! isset( $languages[ $lang_id ] ) ) { return $translation[ $lang_id ] = array( 'status' => 'error', 'msg' => __( 'Translation for selected language not found!', 'publisher' ), ); } // translation data from core if ( $languages[ $lang_id ]['type'] === 'core' && class_exists( 'BetterFramework_Oculus' ) ) { $core_translation = BetterFramework_Oculus::request( 'get-translation', array( 'group' => 'translation', 'json_assoc' => true, 'data' => array( 'code' => $lang_id ) ) ); if ( is_wp_error( $core_translation ) ) { return $translation[ $lang_id ] = array( 'status' => 'Error', 'error_code' => $core_translation->get_error_code(), 'error_message' => $core_translation->get_error_message(), ); } if ( ! empty( $core_translation['success'] ) && ! empty( $core_translation['translation']['translation'] ) ) { return $translation[ $lang_id ] = array( 'status' => 'success', 'translation' => json_decode( $core_translation['translation']['translation'], true ), ); } if ( isset( $core_translation['result'] ) && 'error' === $core_translation['result'] ) { return array( 'status' => 'error', 'msg' => isset( $core_translation['error-message'] ) ? $core_translation['error-message'] : __( 'unknown error occurred.', 'publisher' ), ); } } // url is not found for online if ( ! isset( $languages[ $lang_id ]['url'] ) ) { return $translation[ $lang_id ] = array( 'status' => 'error', 'msg' => __( 'Translation for selected language not found!', 'publisher' ), ); } /** * Filter translation file url * * @since 1.0.0 */ $translation_url = apply_filters( 'publisher-theme-core/translation/change-translation/file-url', $languages[ $lang_id ]['url'] ); // Read translation json file $translation_options_data = wp_remote_get( $translation_url ); if ( is_wp_error( $translation_options_data ) ) { return $translation[ $lang_id ] = array( 'status' => 'Error', 'error_code' => $translation_options_data->get_error_code(), 'error_message' => $translation_options_data->get_error_message(), ); } // request is not 200 $http_code = wp_remote_retrieve_response_code( $translation_options_data ); if ( $http_code !== 200 ) { return $translation[ $lang_id ] = array( 'status' => 'error', 'error_code' => 'http-code-error', 'error_message' => sprintf( __( 'Http request code was %s', 'publisher' ), $http_code ), ); } // file body is not valid $translation_options_data = wp_remote_retrieve_body( $translation_options_data ); if ( ! $translation_options_data ) { return $translation[ $lang_id ] = array( 'status' => 'error', 'msg' => __( 'Translation file for selected language not found!', 'publisher' ), ); } return $translation[ $lang_id ] = array( 'status' => 'success', 'translation' => json_decode( $translation_options_data, true ), ); } }