plugin = $plugin;
}
public function register() {
add_action( 'admin_menu', array( $this, 'add_menu' ), 35 );
add_action( 'admin_init', array( $this, 'remove_legacy_customer_settings' ) );
add_action( 'admin_init', array( $this, 'maybe_redirect_legacy_page' ), 20 );
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ), 120 );
add_filter( 'divi_powers_product_nav_links', array( $this, 'navigation_links' ), 35 );
add_filter( 'divi_powers_submenu_order', array( $this, 'submenu_order' ), 35 );
add_filter( 'divi_powers_dashboard_cards', array( $this, 'dashboard_cards' ), 35, 2 );
add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 35, 2 );
}
public function add_menu() {
add_submenu_page(
'divi-powers',
__( '5D Powers for Divi Help & Support', '5d-powers-for-divi' ),
__( 'Help & Support', '5d-powers-for-divi' ),
'manage_options',
self::PAGE_SLUG,
array( $this, 'render_page' )
);
// Preserve the old Beta Resources URL without keeping a duplicate menu item.
add_submenu_page(
null,
__( '5D Powers for Divi Help & Support', '5d-powers-for-divi' ),
__( 'Help & Support', '5d-powers-for-divi' ),
'manage_options',
self::LEGACY_SLUG,
array( $this, 'render_legacy_page' )
);
}
public function remove_legacy_customer_settings() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
if ( false !== get_option( self::LEGACY_OPTION_KEY, false ) ) {
delete_option( self::LEGACY_OPTION_KEY );
}
}
public function maybe_redirect_legacy_page() {
if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) {
return;
}
$page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( self::LEGACY_SLUG !== $page ) {
return;
}
wp_safe_redirect( admin_url( 'admin.php?page=' . self::PAGE_SLUG ) );
exit;
}
public function render_legacy_page() {
wp_safe_redirect( admin_url( 'admin.php?page=' . self::PAGE_SLUG ) );
exit;
}
public function enqueue_assets() {
$page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( self::PAGE_SLUG !== $page ) {
return;
}
wp_enqueue_style(
'divi-powers-support',
DIVI_POWERS_URL . 'assets/css/support.css',
array( 'divi-powers-admin', 'divi-powers-product-experience' ),
DIVI_POWERS_VERSION
);
wp_enqueue_script(
'divi-powers-support',
DIVI_POWERS_URL . 'assets/js/support.js',
array( 'wp-i18n' ),
DIVI_POWERS_VERSION,
true
);
wp_set_script_translations( 'divi-powers-support', '5d-powers-for-divi' );
$settings = $this->settings();
$context = $this->support_context();
$edition = $this->edition_slug();
wp_localize_script(
'divi-powers-support',
'DiviPowersSupport',
array(
'widgetEnabled' => ! empty( $settings['enable_admin_widget'] ) && ! empty( $settings['tawk_property_id'] ),
'propertyId' => $settings['tawk_property_id'],
'widgetId' => $settings['tawk_widget_id'] ? $settings['tawk_widget_id'] : 'default',
'directChatUrl' => $settings['direct_chat_url'],
'knowledgeBaseUrl' => $settings['knowledge_base_url'],
'attributes' => $context,
'tags' => array_values( array_unique( array( 'divi-powers', $edition, 'wordpress-admin', 'support' ) ) ),
'filename' => 'divi-powers-support-report-' . gmdate( 'Y-m-d' ) . '.txt',
'strings' => array(
'copied' => __( 'Copied', '5d-powers-for-divi' ),
'copyFailed' => __( 'Select and copy the report manually.', '5d-powers-for-divi' ),
'opening' => __( 'Opening support chat…', '5d-powers-for-divi' ),
'chatFailed' => __( 'The embedded chat could not load. Opening the direct chat link instead.', '5d-powers-for-divi' ),
'chatMissing' => __( 'Support chat is temporarily unavailable.', '5d-powers-for-divi' ),
'reportReady' => __( 'The report is copied. Paste it into the support chat when requested.', '5d-powers-for-divi' ),
),
)
);
}
public function navigation_links( $links ) {
$links = is_array( $links ) ? $links : array();
$out = array();
$added = false;
foreach ( $links as $slug => $label ) {
if ( ! $added && 'divi-powers-upgrade' === $slug ) {
$out[ self::PAGE_SLUG ] = __( 'Help & Support', '5d-powers-for-divi' );
$added = true;
}
$out[ $slug ] = $label;
}
if ( ! $added ) {
$out[ self::PAGE_SLUG ] = __( 'Help & Support', '5d-powers-for-divi' );
}
return $out;
}
public function submenu_order( $order ) {
$order = is_array( $order ) ? $order : array();
$order[ self::PAGE_SLUG ] = 90;
return $order;
}
public function dashboard_cards( $cards, $setup ) {
unset( $setup );
$cards = is_array( $cards ) ? $cards : array();
$card = array(
'number' => (string) ( count( $cards ) + 1 ),
'title' => __( 'Get help without leaving WordPress', '5d-powers-for-divi' ),
'description' => __( 'Search the knowledge base, open support chat, submit a ticket, or copy a privacy-conscious system report.', '5d-powers-for-divi' ),
'url' => admin_url( 'admin.php?page=' . self::PAGE_SLUG ),
'link' => __( 'Open Help & Support →', '5d-powers-for-divi' ),
'class' => 'is-support-card',
'badge' => __( 'SUPPORT', '5d-powers-for-divi' ),
'badge_tone' => 'lite',
);
$cards[] = $card;
return $cards;
}
public function plugin_row_meta( $links, $file ) {
if ( plugin_basename( DIVI_POWERS_FILE ) !== $file ) {
return $links;
}
$settings = $this->settings();
if ( ! empty( $settings['knowledge_base_url'] ) ) {
$links[] = '' . esc_html__( 'Knowledge Base', '5d-powers-for-divi' ) . ' ';
}
$links[] = '' . esc_html__( 'Help & Support', '5d-powers-for-divi' ) . ' ';
return $links;
}
public function render_page() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$settings = $this->settings();
$snapshot = $this->support_snapshot();
$widget_ready = ! empty( $settings['enable_admin_widget'] ) && ! empty( $settings['tawk_property_id'] );
$chat_ready = $widget_ready || ! empty( $settings['direct_chat_url'] );
?>
render_action_card( '01', 'dashicons-book-alt', __( 'Search the knowledge base', '5d-powers-for-divi' ), __( 'Search setup, feature, and troubleshooting guides for 5D Powers for Divi.', '5d-powers-for-divi' ), $settings['knowledge_base_url'], __( 'Open knowledge base', '5d-powers-for-divi' ) ); ?>
render_chat_card( $chat_ready, $widget_ready, $settings['direct_chat_url'] ); ?>
render_action_card( '03', 'dashicons-sos', __( 'Submit a support ticket', '5d-powers-for-divi' ), __( 'Use a ticket for bugs, compatibility issues, billing questions, or anything that needs investigation and follow-up.', '5d-powers-for-divi' ), $settings['ticket_url'], __( 'Create support ticket', '5d-powers-for-divi' ) ); ?>
render_action_card( '04', 'dashicons-megaphone', __( 'Share feedback', '5d-powers-for-divi' ), __( 'Tell us what feels confusing, what is missing, and what would make 5D Powers for Divi more useful in a real workflow.', '5d-powers-for-divi' ), $settings['feedback_url'], __( 'Send feedback', '5d-powers-for-divi' ) ); ?>
→
02
→
→
'DIVI_POWERS_SUPPORT_KB_URL',
'ticket_url' => 'DIVI_POWERS_SUPPORT_TICKET_URL',
'direct_chat_url' => 'DIVI_POWERS_TAWK_DIRECT_CHAT_URL',
'feedback_url' => 'DIVI_POWERS_SUPPORT_FEEDBACK_URL',
'tawk_property_id' => 'DIVI_POWERS_TAWK_PROPERTY_ID',
'tawk_widget_id' => 'DIVI_POWERS_TAWK_WIDGET_ID',
);
foreach ( $constant_map as $key => $constant ) {
if ( defined( $constant ) && constant( $constant ) ) {
$data[ $key ] = (string) constant( $constant );
}
}
if ( defined( 'DIVI_POWERS_TAWK_ADMIN_WIDGET' ) ) {
$data['enable_admin_widget'] = DIVI_POWERS_TAWK_ADMIN_WIDGET ? 1 : 0;
}
return $data;
}
private static function defaults() {
return array(
'knowledge_base_url' => 'https://divipowers.com/docs/',
'ticket_url' => 'https://divipowers.com/support/',
'direct_chat_url' => '',
'feedback_url' => 'https://divipowers.com/beta-feedback/',
'tawk_property_id' => '',
'tawk_widget_id' => 'default',
'enable_admin_widget'=> 0,
);
}
private function edition_slug() {
if ( Divi_Powers_Plugin::is_pro_active() ) {
return 'pro';
}
if ( Divi_Powers_Plugin::is_plus_active() ) {
return 'plus';
}
return 'lite';
}
private function support_context() {
$theme = wp_get_theme();
$divi_theme = wp_get_theme( 'Divi' );
$site_host = wp_parse_url( home_url( '/' ), PHP_URL_HOST );
$divi_version = $divi_theme->exists() ? $divi_theme->get( 'Version' ) : '';
return array(
'product' => 'Divi Powers',
'edition' => $this->edition_slug(),
'lite-version' => defined( 'DIVI_POWERS_VERSION' ) ? DIVI_POWERS_VERSION : '',
'plus-version' => defined( 'DIVI_POWERS_PLUS_VERSION' ) ? DIVI_POWERS_PLUS_VERSION : 'not-active',
'pro-version' => defined( 'DIVI_POWERS_PRO_VERSION' ) ? DIVI_POWERS_PRO_VERSION : 'not-active',
'wordpress-version' => get_bloginfo( 'version' ),
'php-version' => PHP_VERSION,
'divi-version' => $divi_version ? $divi_version : 'not-detected',
'woo-version' => defined( 'WC_VERSION' ) ? WC_VERSION : 'not-active',
'theme' => trim( $theme->get( 'Name' ) . ' ' . $theme->get( 'Version' ) ),
'site-host' => $site_host ? $site_host : 'unknown',
'current-screen' => 'help-support',
);
}
private function support_snapshot() {
global $wpdb;
if ( ! function_exists( 'get_plugins' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$theme = wp_get_theme();
$parent_theme = $theme->parent();
$divi_theme = wp_get_theme( 'Divi' );
$setup = class_exists( 'Divi_Powers_Onboarding' ) ? Divi_Powers_Onboarding::setup_summary() : array();
$enabled = $this->plugin->enabled_powers();
$site_host = wp_parse_url( home_url( '/' ), PHP_URL_HOST );
$plugins = $this->active_plugin_labels();
sort( $enabled );
sort( $plugins );
$rows = array(
'DIVI POWERS SUPPORT REPORT',
'Generated: ' . gmdate( 'Y-m-d H:i:s' ) . ' UTC',
'Site host: ' . ( $site_host ? $site_host : 'Unknown' ),
'',
'PRODUCT',
'Divi Powers edition: ' . ucfirst( $this->edition_slug() ),
'5D Powers for Divi Free: ' . ( defined( 'DIVI_POWERS_VERSION' ) ? DIVI_POWERS_VERSION : 'Not active' ),
'Divi Powers Plus: ' . ( defined( 'DIVI_POWERS_PLUS_VERSION' ) ? DIVI_POWERS_PLUS_VERSION : 'Not active' ),
'5D Powers for Divi Pro: ' . ( defined( 'DIVI_POWERS_PRO_VERSION' ) ? DIVI_POWERS_PRO_VERSION : 'Not active' ),
'Enabled Powers: ' . ( $enabled ? implode( ', ', $enabled ) : 'None' ),
'Starter page installed: ' . ( ! empty( $setup['starter_ok'] ) ? 'Yes' : 'No' ),
'Starter page native: ' . ( ! empty( $setup['lite_demo_native'] ) || ! empty( $setup['pro_starter_native'] ) ? 'Yes' : 'No' ),
'',
'WORDPRESS',
'WordPress: ' . get_bloginfo( 'version' ),
'Locale: ' . get_locale(),
'Multisite: ' . ( is_multisite() ? 'Yes' : 'No' ),
'WP_DEBUG: ' . ( defined( 'WP_DEBUG' ) && WP_DEBUG ? 'On' : 'Off' ),
'SCRIPT_DEBUG: ' . ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'On' : 'Off' ),
'WordPress memory limit: ' . ( defined( 'WP_MEMORY_LIMIT' ) ? WP_MEMORY_LIMIT : 'Unknown' ),
'WordPress max memory limit: ' . ( defined( 'WP_MAX_MEMORY_LIMIT' ) ? WP_MAX_MEMORY_LIMIT : 'Unknown' ),
'',
'ENVIRONMENT',
'PHP: ' . PHP_VERSION,
'Database: ' . ( is_object( $wpdb ) && method_exists( $wpdb, 'db_version' ) ? $wpdb->db_version() : 'Unknown' ),
'Web server: ' . ( isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : 'Unknown' ),
'PHP memory_limit: ' . (string) ini_get( 'memory_limit' ),
'PHP max_execution_time: ' . (string) ini_get( 'max_execution_time' ),
'PHP max_input_vars: ' . (string) ini_get( 'max_input_vars' ),
'PHP post_max_size: ' . (string) ini_get( 'post_max_size' ),
'PHP upload_max_filesize: ' . (string) ini_get( 'upload_max_filesize' ),
'',
'THEME & BUILDER',
'Active theme: ' . trim( $theme->get( 'Name' ) . ' ' . $theme->get( 'Version' ) ),
'Parent theme: ' . ( $parent_theme ? trim( $parent_theme->get( 'Name' ) . ' ' . $parent_theme->get( 'Version' ) ) : 'None' ),
'Divi theme: ' . ( $divi_theme->exists() ? $divi_theme->get( 'Version' ) : 'Not detected' ),
'Divi detected: ' . ( function_exists( 'et_builder_d5_enabled' ) ? 'Yes' : 'No' ),
'Divi 5 enabled: ' . ( function_exists( 'et_builder_d5_enabled' ) && et_builder_d5_enabled() ? 'Yes' : 'No' ),
'Divi Builder extension API: ' . ( class_exists( '\\ET\\Builder\\VisualBuilder\\Assets\\PackageBuildManager' ) ? 'Available' : 'Not detected' ),
'WooCommerce: ' . ( defined( 'WC_VERSION' ) ? WC_VERSION : 'Not active' ),
'',
'ACTIVE PLUGINS (' . count( $plugins ) . ')',
);
foreach ( $plugins as $plugin ) {
$rows[] = '- ' . $plugin;
}
$rows[] = '';
$rows[] = 'BROWSER';
$rows[] = 'User agent: [added locally by the Help & Support screen]';
$rows[] = '';
$rows[] = 'PRIVACY';
$rows[] = 'This report excludes license keys, passwords, API secrets, authentication cookies, customer records, orders, form submissions, page content, and database credentials.';
return implode( "\n", $rows );
}
private function active_plugin_labels() {
$all_plugins = get_plugins();
$active = array_flip( (array) get_option( 'active_plugins', array() ) );
$network = is_multisite() ? (array) get_site_option( 'active_sitewide_plugins', array() ) : array();
$labels = array();
foreach ( $all_plugins as $file => $data ) {
if ( ! isset( $active[ $file ] ) && ! isset( $network[ $file ] ) ) {
continue;
}
$name = isset( $data['Name'] ) ? wp_strip_all_tags( $data['Name'] ) : $file;
$version = isset( $data['Version'] ) ? wp_strip_all_tags( $data['Version'] ) : '';
$labels[] = trim( $name . ' ' . $version ) . ( isset( $network[ $file ] ) ? ' [Network active]' : '' );
}
return $labels;
}
}