KOKINIO - MANAGER
Edit File: class-hustle-admin-page-abstract.php
<?php /** * File for Hustle_Admin_Page_Abstract class. * * @package Hustle * @since 4.0.1 */ if ( ! class_exists( 'Hustle_Admin_Page_Abstract' ) ) : /** * Class Hustle_Admin_Page_Abstract. * This is the base class for all Hustle's pages. * * @since 4.0.1 */ abstract class Hustle_Admin_Page_Abstract { /** * Page slug defined by us. * * @since 4.0.1 * @var string */ protected $page; /** * Template path for the page relative to the 'views' folder. * * @since 4.0.1 * @var string */ protected $page_template_path; /** * Page title. * * @since 4.0.1 * @var string */ protected $page_title; /** * Page title for the WordPress menu. * * @since 4.0.1 * @var string */ protected $page_menu_title; /** * Required capability for the page to be available. * * @since 4.0.1 * @var string */ protected $page_capability; /** * The current page that's being requested. * * @since 4.0.2 * @var string|bool */ protected $current_page; /** * Page slug defined by WordPress when registering the page. * * @since 4.0.0 * @var string */ protected $page_slug; /** * Instance of Hustle_Layout_Helper * * @since 4.2.0 * @var Hustle_Layout_Helper */ private $renderer; /** * Class constructor. * * @since 4.0.1 */ public function __construct() { $this->current_page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_SPECIAL_CHARS ); $this->init(); add_action( 'admin_menu', array( $this, 'register_admin_menu' ) ); } /** * Initiate the page's properties * Should be overridden by each page. * * @since 4.0.1 */ abstract protected function init(); /** * Get the template arguments for the page. * * @since 7.8.9 * @return array */ abstract protected function get_page_template_args(); /** * Register the admin menus. * * @since 4.0.1 */ public function register_admin_menu() { $this->page_slug = add_submenu_page( 'hustle', $this->page_title, esc_html( $this->page_menu_title ), $this->page_capability, $this->page, array( $this, 'render_main_page' ) ); add_action( 'admin_init', array( $this, 'maybe_export' ) ); add_action( 'load-' . $this->page_slug, array( $this, 'current_page_loaded' ) ); } /** * Gets an instance of the renderer class. * * @since 4.2.1 * @return Hustle_Layout_Helper */ protected function get_renderer() { if ( ! $this->renderer ) { $this->renderer = new Hustle_Layout_Helper( $this ); } return $this->renderer; } /** * Check if it's export - run the relevant action. */ public function maybe_export() { $this->export_module(); } /** * Render the main page * * @since 4.0.1 */ public function render_main_page() { ?> <div class="<?php echo esc_attr( $this->get_sui_wrap_class() ); ?>"> <?php $template_args = $this->get_page_template_args(); $renderer = $this->get_renderer(); $renderer->render( $this->page_template_path, $template_args ); $this->render_modals(); ?> </div> <?php } /** * Perform actions during the 'load-{page}' hook. * * @since 4.0.4 */ public function current_page_loaded() { $this->maybe_export(); add_action( 'admin_enqueue_scripts', array( $this, 'register_scripts' ), 99 ); add_action( 'admin_print_styles', array( $this, 'register_styles' ) ); add_filter( 'admin_body_class', array( $this, 'add_admin_body_class' ), 99 ); add_filter( 'removable_query_args', array( $this, 'remove_notice_params' ) ); } /** * Print forminator scripts for preview. * Used by Dashboard, Wizards, and Listings. * * @since 4.0.1 */ public function maybe_print_forminator_scripts() { // Add Forminator's front styles and scripts for preview. if ( defined( 'FORMINATOR_VERSION' ) ) { forminator_print_front_styles( FORMINATOR_VERSION ); forminator_print_front_scripts( FORMINATOR_VERSION ); } } /** * Register scripts for the admin page. * * @since 4.3.1 * * @param string $page_slug Page slug. */ public function register_scripts( $page_slug ) { wp_enqueue_script( 'shared-ui', Opt_In::$plugin_url . 'assets/js/shared-ui.min.js', array( 'jquery' ), HUSTLE_SUI_VERSION, true ); /** * Filters the variable to be localized into the js side of Hustle's admin pages. * * @since unknown */ $optin_vars = apply_filters( 'hustle_optin_vars', $this->get_vars_to_localize() ); wp_register_script( 'optin_admin_scripts', Opt_In::$plugin_url . 'assets/js/admin.min.js', array( 'jquery', 'backbone', 'jquery-effects-core', 'shared-ui' ), Opt_In::VERSION, true ); wp_localize_script( 'optin_admin_scripts', 'optinVars', $optin_vars ); wp_enqueue_script( 'optin_admin_scripts' ); } /** * Register the js variables to be localized for this page. * * @since 4.3.1 * * @return array */ protected function get_vars_to_localize() { $tutorials_removed = sprintf( /* translators: %1$s - plugin name, %2$s - opening <a> tag, %3$s - closing <a> tag */ esc_html__( 'The widget has been removed. %1$s tutorials can still be found in the %2$sTutorials tab%3$s any time.', 'hustle' ), Opt_In_Utils::get_plugin_name(), '<a href=' . esc_url( menu_page_url( 'hustle_tutorials', false ) ) . '>', '</a>' ); $url_params = $_GET; // phpcs:ignore WordPress.Security.NonceVerification.Recommended array_walk_recursive( $url_params, function ( &$val ) { $val = esc_attr( $val ); } ); return array( 'ss_preview_nonce' => wp_create_nonce( 'hustle-preview' ), 'dismiss_notice_nonce' => wp_create_nonce( 'hustle_dismiss_notification' ), 'urlParams' => $url_params, 'module_page' => array( 'popup' => Hustle_Data::POPUP_LISTING_PAGE, 'slidein' => Hustle_Data::SLIDEIN_LISTING_PAGE, 'embedded' => Hustle_Data::EMBEDDED_LISTING_PAGE, 'social_sharing' => Hustle_Data::SOCIAL_SHARING_LISTING_PAGE, ), 'messages' => array( 'something_went_wrong' => esc_html__( 'Something went wrong. Please try again', 'hustle' ), // everywhere. 'something_went_wrong_reload' => '<label class="wpmudev-label--notice"><span>' . esc_html__( 'Something went wrong. Please reload this page and try again.', 'hustle' ) . '</span></label>', // everywhere. /* translators: "Aweber" between "strong" tags */ 'aweber_migration_success' => sprintf( esc_html__( '%s integration successfully migrated to the oAuth 2.0.', 'hustle' ), '<strong>' . esc_html__( 'Aweber', 'hustle' ) . '</strong>' ), // everywhere. views.js. 'integraiton_required' => '<label class="wpmudev-label--notice"><span>' . esc_html__( 'An integration is required on opt-in module.', 'hustle' ) . '</span></label>', // wizard and integrations. 'module_deleted' => esc_html__( 'Module successfully deleted.', 'hustle' ), // listing and dashboard. 'shortcode_copied' => esc_html__( 'Shortcode copied successfully.', 'hustle' ), // listing and dashboard. 'commons' => array( 'published' => esc_html__( 'Published', 'hustle' ), // dashboard and wizard. 'draft' => esc_html__( 'Draft', 'hustle' ), // dashboard and wizard. 'dismiss' => esc_html__( 'Dismiss', 'hustle' ), // everywhere, views.js. ), 'request_error_reload_notice' => esc_html__( 'There was an issue processing your request. Please reload the page and try again.', 'hustle' ), ), ); } /** * Registers styles for the admin pages. * * @since 4.3.1 * * @param string $page_slug Slug of the current page. */ public function register_styles( $page_slug ) { wp_enqueue_style( 'thickbox' ); wp_register_style( 'hstl-roboto', 'https://fonts.bunny.net/css?family=Roboto+Condensed:300,300i,400,400i,700,700i|Roboto:300,300i,400,400i,500,500i,700,700i', array(), Opt_In::VERSION ); wp_register_style( 'hstl-opensans', 'https://fonts.bunny.net/css?family=Open+Sans:400,400i,700,700i', array(), Opt_In::VERSION ); wp_register_style( 'hstl-source', 'https://fonts.bunny.net/css?family=Source+Code+Pro', array(), Opt_In::VERSION ); wp_enqueue_style( 'wp-color-picker' ); wp_enqueue_style( 'wdev_ui' ); wp_enqueue_style( 'wdev_notice' ); wp_enqueue_style( 'hstl-roboto' ); wp_enqueue_style( 'hstl-opensans' ); wp_enqueue_style( 'hstl-source' ); wp_enqueue_style( 'sui_styles', Opt_In::$plugin_url . 'assets/css/shared-ui.min.css', array(), HUSTLE_SUI_VERSION ); } /** * Adds a class to the page body with the SUI version. * * @since 4.3.1 * * @param string $classes Current set of classes to be added. * @return string */ public function add_admin_body_class( $classes ) { $formatted_version = str_replace( '.', '-', HUSTLE_SUI_VERSION ); $classes .= ' sui-' . $formatted_version; /** * Add high contrast mode. */ $accessibility = Hustle_Settings_Admin::get_hustle_settings( 'accessibility' ); $is_high_contrast_mode = ! empty( $accessibility['accessibility_color'] ); if ( $is_high_contrast_mode ) { $classes .= ' sui-elements-accessible'; } return $classes; } /** * Remove Get parameters for Hustle notices * * @since 4.3.1 * * @param string[] $vars An array of query variables to remove from a URL. * @return array */ public function remove_notice_params( $vars ) { $vars[] = 'show-notice'; $vars[] = 'notice'; $vars[] = 'notice-close'; return $vars; } /** * Exports a single module. * Used by Dashboard and Listing. * * @since 4.0.0 * @since 4.2.0 Moved from Hustle_Modules_Common_Admin to this class. */ protected function export_module() { $nonce = filter_input( INPUT_POST, '_wpnonce', FILTER_SANITIZE_SPECIAL_CHARS ); if ( ! wp_verify_nonce( $nonce, 'hustle_module_export' ) ) { return; } $id = filter_input( INPUT_POST, 'id', FILTER_VALIDATE_INT ); if ( ! $id ) { return; } // Plugin data. $plugin = get_plugin_data( WP_PLUGIN_DIR . '/' . Opt_In::$plugin_base_file ); // Get module. $module = Hustle_Module_Model::new_instance( $id ); if ( is_wp_error( $module ) ) { return; } // Export data. $settings = array( 'plugin' => array( 'name' => $plugin['Name'], 'version' => Opt_In::VERSION, 'network' => $plugin['Network'], ), 'timestamp' => time(), 'attributes' => $module->get_attributes(), 'data' => $module->get_data(), 'meta' => array(), ); if ( 'optin' === $module->module_mode ) { $integrations = array(); $providers = Hustle_Providers::get_instance()->get_providers(); foreach ( $providers as $slug => $provider ) { $provider_data = $module->get_provider_settings( $slug, false ); if ( $provider_data && $provider->is_connected() && $provider->is_form_connected( $id ) ) { $integrations[ $slug ] = $provider_data; } } $settings['meta']['integrations'] = $integrations; } $meta_names = $module->get_module_meta_names(); foreach ( $meta_names as $meta_key ) { $settings['meta'][ $meta_key ] = json_decode( $module->get_meta( $meta_key ) ); } /** * Filename */ $filename = sprintf( 'hustle-%s-%s-%s-%s.json', $module->module_type, gmdate( 'Ymd-his' ), get_bloginfo( 'name' ), $module->module_name ); if ( ob_get_contents() ) { // To prevent other plugins' errors fail the export. ob_clean(); } $filename = strtolower( $filename ); $filename = sanitize_file_name( $filename ); /** * Print HTTP headers */ header( 'Content-Description: File Transfer' ); header( 'Content-Disposition: attachment; filename=' . $filename ); header( 'Content-Type: application/bin; charset=' . get_option( 'blog_charset' ), true ); /** * Check PHP version, for PHP < 3 do not add options */ $version = phpversion(); $compare = version_compare( $version, '5.3', '<' ); if ( $compare ) { echo wp_json_encode( $settings ); exit; } $option = defined( 'JSON_PRETTY_PRINT' ) ? JSON_PRETTY_PRINT : null; echo wp_json_encode( $settings, $option ); exit; } /** * Filter related to TinyMCE * Used by Settings and Wizard pages. * * @since 4.2.0 Moved from Hustle_Module_Admin to this class. */ protected function set_up_tinymce() { add_filter( 'tiny_mce_before_init', array( $this, 'set_tinymce_settings' ), 10, 2 ); add_filter( 'wp_default_editor', array( $this, 'set_editor_to_tinymce' ) ); add_filter( 'tiny_mce_plugins', array( $this, 'remove_despised_editor_plugins' ) ); add_filter( 'mce_buttons', array( $this, 'remove_readmore_tag' ) ); } /** * Modify tinymce editor settings. * * @param array $settings Registered settings. * @param string $editor_id Current editor ID. */ public function set_tinymce_settings( $settings, $editor_id ) { $settings['paste_as_text'] = 'true'; return $settings; } /** * Sets default editor to tinymce for opt-in admin * * @param string $editor_type Current editor type. * @return string */ public function set_editor_to_tinymce( $editor_type ) { return 'tinymce'; } /** * Removes unnecessary editor plugins * * @param array $plugins Registered plugins. * @return mixed */ public function remove_despised_editor_plugins( $plugins ) { $k = array_search( 'fullscreen', $plugins, true ); if ( false !== $k ) { unset( $plugins[ $k ] ); } $plugins[] = 'paste'; return $plugins; } /** * Removes the "Read more" tag from the editor. * * @param array $mce_buttons Array of TinyMCE buttons. * @return array */ public function remove_readmore_tag( $mce_buttons ) { $remove = array( 'wp_more' ); return array_diff( $mce_buttons, $remove ); } /** * Gets the current tab the page is on load. * Used by wizards and the global settings page. * * @since 4.3.1 * * @param boolean|string $default_value Default value. * @return boolean|string */ protected function get_current_section( $default_value = false ) { $section = filter_input( INPUT_GET, 'section', FILTER_SANITIZE_SPECIAL_CHARS ); return empty( $section ) ? $default_value : $section; } /** * SUI summary config. * * @since 4.2.0 * * @param string|null $class_name Class to be added. */ protected function get_sui_summary_config( $class_name = null ) { $style = ''; $image_url = apply_filters( 'wpmudev_branding_hero_image', null ); if ( ! empty( $image_url ) ) { $style = 'background-image:url(' . esc_url( $image_url ) . ')'; } $sui = array( 'summary' => array( 'style' => $style, 'classes' => array( 'sui-box', 'sui-summary', ), ), ); if ( ! empty( $class_name ) && is_string( $class_name ) ) { $sui['summary']['classes'][] = $class_name; } /** * Dash integration * * @since 4.0.0 */ $hide_branding = apply_filters( 'wpmudev_branding_hide_branding', false ); $branding_image = apply_filters( 'wpmudev_branding_hero_image', null ); if ( $hide_branding && ! empty( $branding_image ) ) { $sui['summary']['classes'][] = 'sui-rebranded'; } elseif ( $hide_branding && empty( $branding_image ) ) { $sui['summary']['classes'][] = 'sui-unbranded'; } return $sui; } /** * Gets the SUI classes according to the selected setitngs in WPMU Dev dashboard. * * @since 4.3.1 * * @return string */ protected function get_sui_wrap_class() { $classes = array( 'sui-wrap', 'sui-wrap-hustle' ); /** * Add high contrast mode. */ $accessibility = Hustle_Settings_Admin::get_hustle_settings( 'accessibility' ); $is_high_contrast_mode = ! empty( $accessibility['accessibility_color'] ); if ( $is_high_contrast_mode ) { $classes[] = 'sui-color-accessible'; } /** * Set hide branding. * * @since 4.0.0 */ $hide_branding = apply_filters( 'wpmudev_branding_hide_branding', false ); if ( $hide_branding ) { $classes[] = 'no-hustle'; } /** * Hero image. * * @since 4.0.0 */ $image = apply_filters( 'wpmudev_branding_hero_image', 'hustle-default' ); if ( empty( $image ) ) { $classes[] = 'no-hustle-hero'; } $classes = apply_filters( 'hustle_sui_wrap_class', $classes ); return implode( ' ', $classes ); } /** * Renders the modals. * This abstract class renders the modals that are displayed on all hustle's pages. * Each page should override this method to add the specific modals for it. * * @since 4.3.5 */ protected function render_modals() {} /** * Add wp color picker */ protected static function add_color_picker() { // Deregister other similar pickers if they load from other plugins or theme. wp_deregister_script( 'wp-color-picker-alpha' ); wp_register_script( 'wp-color-picker-alpha', Opt_In::$plugin_url . 'assets/js/vendor/wp-color-picker-alpha.min.js', array( 'wp-color-picker' ), '3.0.2', true ); $color_picker_strings = array( 'clear' => esc_html__( 'Clear', 'hustle' ), 'clearAriaLabel' => esc_html__( 'Clear color', 'hustle' ), 'defaultString' => esc_html__( 'Default', 'hustle' ), 'defaultAriaLabel' => esc_html__( 'Select default color', 'hustle' ), 'pick' => esc_html__( 'Select Color', 'hustle' ), 'defaultLabel' => esc_html__( 'Color value', 'hustle' ), ); wp_localize_script( 'wp-color-picker-alpha', 'wpColorPickerL10n', $color_picker_strings ); wp_enqueue_script( 'wp-color-picker-alpha' ); } } endif;