*/ use ShapedPlugin\EasyAccordion\Blocks\Includes\Blocks_Helper; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } if ( ! class_exists( 'Eab_Admin_Dashboard' ) ) { /** * Eab_Admin_Dashboard Class. */ class Eab_Admin_Dashboard { /** * Eab_admin_dashboard_nonce_key. * * @var string */ private $eab_admin_dashboard_nonce_key = 'sp_eap_admin_dashboard_nonce'; /** * Eab_block_visibility_key. * * @var string */ private $eab_block_visibility_key = 'sp_easy_accordion_visibility_settings'; /** * Eap_dashboard_settings_key. * * @var string */ private $eap_dashboard_settings_key = 'sp_eap_dashboard_settings'; /** * Sp_eap_settings_key. * * @var string */ private $sp_eap_settings_key = 'sp_eap_settings'; /** * Eab_show_upgrade_notice_key. * * @var string */ private $eab_show_upgrade_notice_key = 'sp_eab_show_upgrade_notice'; /** * Plugins Path variable. * * @var array */ protected static $plugins = array( 'woo-product-slider' => 'main.php', 'gallery-slider-for-woocommerce' => 'woo-gallery-slider.php', 'post-carousel' => 'main.php', 'woo-quickview' => 'woo-quick-view.php', 'wp-expand-tabs-free' => 'plugin-main.php', 'logo-carousel-free' => 'main.php', ); /** * Block constructor. */ public function __construct() { // admin menu customization. add_action( 'admin_menu', array( $this, 'sp_eab_admin_menu_customize' ) ); // remove admin notices. add_action( 'current_screen', array( $this, 'remove_admin_notices' ) ); // manage ajax request. add_action( 'wp_ajax_sp_eab_admin_option_update', array( $this, 'sp_eab_admin_option_update' ) ); add_action( 'wp_ajax_sp_eap_changelog_data', array( $this, 'sp_eap_changelog_data' ) ); add_action( 'wp_ajax_sp_eap_get_user_consent', array( $this, 'sp_eap_get_user_consent' ) ); add_action( 'wp_ajax_sp_eab_hide_upgrade_notice', array( $this, 'sp_eab_hide_upgrade_notice' ) ); // manage admin dashboard assets. add_action( 'admin_enqueue_scripts', array( $this, 'sp_eab_admin_dashboard_enqueue_admin_assets' ) ); // admin notices. add_action( 'init', array( $this, 'eap_submit_user_consent' ) ); add_action( 'admin_notices', array( $this, 'eap_maybe_show_user_consent_notice' ) ); } /** * Add submenu page for blocks. */ public function sp_eab_admin_menu_customize() { add_submenu_page( 'edit.php?post_type=sp_easy_accordion', __( 'Easy Accordion Pro Dashboard', 'easy-accordion-free' ), __( 'Getting Started', 'easy-accordion-free' ), apply_filters( 'easy_accordion_access_capability', 'manage_options' ), 'eap_dashboard', array( $this, 'blocks_page_wrapper_callback' ) ); // add_submenu_page( // 'edit.php?post_type=sp_easy_accordion', // __( 'Easy Accordion Pro Blocks', 'easy-accordion-free' ), // __( 'Blocks', 'easy-accordion-free' ) . '' . __( ' NEW!', 'easy-accordion-free' ) . '', // apply_filters( 'easy_accordion_access_capability', 'manage_options' ), // 'edit.php?post_type=sp_easy_accordion&page=eap_dashboard#blocks' // ); add_submenu_page( 'edit.php?post_type=sp_easy_accordion', __( 'Easy Accordion Pro Settings', 'easy-accordion-free' ), __( 'Settings', 'easy-accordion-free' ), apply_filters( 'easy_accordion_access_capability', 'manage_options' ), 'edit.php?post_type=sp_easy_accordion&page=eap_dashboard#settings' ); // add_submenu_page( // 'edit.php?post_type=sp_easy_accordion', // __( 'Easy Accordion', 'easy-accordion-free' ), // __( 'Lite vs Pro', 'easy-accordion-free' ), // 'manage_options', // 'edit.php?post_type=sp_easy_accordion&page=eap_dashboard#lite_vs_pro' // ); add_submenu_page( 'edit.php?post_type=sp_easy_accordion', __( 'Upgrade to Pro', 'easy-accordion-free' ), ' Upgrade to Pro ', 'manage_options', 'eab_upgrade_to_pro', '__return_null', ); // Reorder submenu items. add_action( 'admin_menu', function () { global $submenu; $menu_key = 'edit.php?post_type=sp_easy_accordion'; if ( empty( $submenu[ $menu_key ] ) ) { return; } $items = $submenu[ $menu_key ]; // Index submenu items by slug. $indexed = array(); foreach ( $items as $item ) { $indexed[ $item[2] ] = $item; } // Define priority order (these will appear first). $priority_items = array( 'eap_dashboard', 'edit.php?post_type=sp_easy_accordion&page=eap_dashboard#blocks', 'edit.php?post_type=sp_easy_accordion&page=eap_dashboard#saved_templates', 'edit.php?post_type=sp_easy_accordion', 'post-new.php?post_type=sp_easy_accordion', 'edit.php?post_type=sp_accordion_faqs', 'post-new.php?post_type=sp_accordion_faqs', 'eap_form', 'eap_analytics', 'edit.php?post_type=sp_easy_accordion&page=eap_dashboard#settings', 'eap_tools', 'edit.php?post_type=sp_easy_accordion&page=eap_dashboard#lite_vs_pro', 'eab_upgrade_to_pro', ); $new_menu = array(); // Add priority items first. foreach ( $priority_items as $slug ) { if ( isset( $indexed[ $slug ] ) ) { $new_menu[] = $indexed[ $slug ]; unset( $indexed[ $slug ] ); } } // Append remaining submenu items automatically. foreach ( $indexed as $item ) { $new_menu[] = $item; } // Replace submenu. // phpcs:disable WordPress.WP.GlobalVariablesOverride.Prohibited $submenu[ $menu_key ] = $new_menu; // phpcs:enable }, 999 ); } /** * Callback function for the blocks page. */ public function blocks_page_wrapper_callback() { // Handle activation/deactivation requests that come back via the action links. $action = isset( $_GET['action'] ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; $plugin = isset( $_GET['plugin'] ) ? sanitize_text_field( wp_unslash( $_GET['plugin'] ) ) : ''; $_wpnonce = isset( $_GET['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ) : ''; if ( isset( $action, $plugin ) && 'activate' === $action && wp_verify_nonce( $_wpnonce, 'activate-plugin_' . $plugin ) ) { if ( current_user_can( 'activate_plugins' ) ) { activate_plugin( $plugin, '', false, true ); } } ?>
'shapedplugin', 'per_page' => '120', 'page' => '1', 'fields' => array( 'slug', 'name', 'version', 'downloaded', 'active_installs', 'last_updated', 'rating', 'num_ratings', 'short_description', 'author', 'icons', ), ); if ( ! function_exists( 'plugins_api' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; } $plugin_info = plugins_api( 'query_plugins', $args ); if ( ! is_wp_error( $plugin_info ) ) { $plugins_arr = array(); if ( isset( $plugin_info->plugins ) && ( count( $plugin_info->plugins ) > 0 ) ) { foreach ( $plugin_info->plugins as $pl ) { $plugins_arr[] = array( 'slug' => $pl['slug'], 'name' => $pl['name'], 'version' => $pl['version'], 'downloaded' => $pl['downloaded'], 'active_installs' => $pl['active_installs'], 'last_updated' => strtotime( $pl['last_updated'] ), 'rating' => $pl['rating'], 'num_ratings' => $pl['num_ratings'], 'short_description' => $pl['short_description'], 'icons' => $pl['icons']['2x'], ); } } set_transient( 'spea_plugins_data', $plugins_arr, 24 * HOUR_IN_SECONDS ); } } if ( is_array( $plugins_arr ) && ( count( $plugins_arr ) > 0 ) ) { $no_of_active_installs = array_column( $plugins_arr, 'active_installs' ); array_multisort( $no_of_active_installs, SORT_DESC, $plugins_arr ); foreach ( $plugins_arr as $plugin ) { $plugin_slug = $plugin['slug']; $plugin_icon = $plugin['icons']; if ( isset( self::$plugins[ $plugin_slug ] ) ) { $plugin_file = self::$plugins[ $plugin_slug ]; } else { $plugin_file = $plugin_slug . '.php'; } // Skip the plugin if it is not installed. if ( 'easy-accordion-free' === $plugin_slug ) { continue; } $details_link = network_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . $plugin['slug'] . '&TB_iframe=true&width=745&height=550' ); ?>

'; if ( isset( $plugin['rating'], $plugin['num_ratings'] ) ) { ?>
$plugin['rating'], 'type' => 'percent', 'number' => $plugin['num_ratings'], ) ); ?> ()
'; ?>
get_dashboard_settings(); $current_user = wp_get_current_user(); $user_name = $current_user->display_name; /** * Admin Settings page localization. */ wp_localize_script( 'sp-eab-admin-dashboard-script', 'sp_eab_admin_dashboard_localize', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'pluginUrl' => SP_EA_URL, 'pluginVersion' => SP_EA_VERSION, 'isActiveWooCommerce' => $is_active_woocommerce, 'homeUrl' => home_url( '/' ), 'dashboardInfo' => $dashboard_settings, 'nonce' => wp_create_nonce( $this->eab_admin_dashboard_nonce_key ), 'eab_user_consent' => $dashboard_settings['eap_allow_anonymous_data'] ?? 'undefined', 'userName' => $user_name, 'eap_editor_preference' => get_option( 'ea_free_blocks_promo_modal_choice', '' ), 'showUpgradeNotice' => $this->should_show_upgrade_notice(), 'savedTemplatesUrl' => admin_url( 'edit.php?post_type=sp_easy_accordion&page=eap_dashboard#saved_templates' ), ) ); } /** * Blocks admin panel settings option update function. * * @return void * */ public function sp_eab_admin_option_update() { // Check user capabilities, current_user_can() is called internally. Blocks_Helper::sp_eap_verify_capability(); // Verify nonce. $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, $this->eab_admin_dashboard_nonce_key ) ) { wp_send_json_error( array( 'message' => 'Security check failed.' ), 403 ); return; } $query_data = isset( $_POST['queryData'] ) ? sanitize_text_field( wp_unslash( $_POST['queryData'] ) ) : ''; $query_data = (array) json_decode( $query_data, true ); // manage visibility options. $visibility_option = $query_data['blockVisibility'] ?? array(); if ( ! empty( $visibility_option ) ) { update_option( $this->eab_block_visibility_key, $visibility_option ); } // manage plugin settings options. $plugin_settings = $query_data['pluginSettings'] ?? array(); if ( ! empty( $plugin_settings ) ) { update_option( $this->sp_eap_settings_key, $plugin_settings ); } // update dashboard settings. $dashboard_settings = $query_data['dashboardSettings'] ?? array(); if ( ! empty( $dashboard_settings ) ) { update_option( $this->eap_dashboard_settings_key, $dashboard_settings ); } // Handle editor preference for promo modal. if ( isset( $_POST['editorPreference'] ) ) { $editor_preference = sanitize_key( wp_unslash( $_POST['editorPreference'] ) ); $allowed_editors = array( 'block_editor', 'classic_shortcode' ); if ( in_array( $editor_preference, $allowed_editors, true ) ) { update_option( 'ea_free_blocks_promo_modal_choice', $editor_preference, false ); } else { delete_option( 'ea_free_blocks_promo_modal_choice' ); } } // send response. $query_response = array( 'pluginSettings' => get_option( $this->sp_eap_settings_key, array() ), 'blockVisibility' => get_option( $this->eab_block_visibility_key, array() ), 'eapShortcodes' => Blocks_Helper::sp_easy_accordion_pro_post_list(), 'dashboardSettings' => $this->get_dashboard_settings(), ); wp_send_json( $query_response ); } /** * Handles the AJAX request to hide the upgrade notice. * * - Updates the option to false when user clicks the close button. * - Returns success response. * * @return void */ public function sp_eab_hide_upgrade_notice() { // Check user capabilities. Blocks_Helper::sp_eap_verify_capability(); // Verify nonce. $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, $this->eab_admin_dashboard_nonce_key ) ) { wp_send_json_error( array( 'message' => 'Security check failed.' ), 403 ); return; } // Update the option to hide the notice. update_option( $this->eab_show_upgrade_notice_key, 'hide' ); // Send success response. wp_send_json_success( array( 'message' => 'Upgrade notice hidden successfully.', ) ); } /** * Check if the upgrade notice should be shown. * * - Returns false if the notice has been dismissed. * - Checks if 3 days have passed since plugin installation. * * @return bool True if notice should be shown, false otherwise. */ public function should_show_upgrade_notice() { // Check if notice is dismissed. $show_notice = get_option( $this->eab_show_upgrade_notice_key, '' ); if ( 'hide' === $show_notice ) { return false; } // Check if 3 days have passed since plugin installation. $installed_at = $this->get_plugin_installation_date(); if ( ! $installed_at ) { // If no installation date is set, set it now and don't show notice yet. $this->set_plugin_installation_date(); return false; } // Calculate days since installation. $days_since_install = ( time() - $installed_at ) / DAY_IN_SECONDS; // Show notice only after 3 days. return $days_since_install >= 3; } /** * Get the plugin installation date. * * @return int|false Timestamp of installation or false if not set. */ private function get_plugin_installation_date() { return get_option( 'easy_accordion_free_activation_date', false ); } /** * Set the plugin installation date. * * @return void */ private function set_plugin_installation_date() { update_option( 'easy_accordion_free_activation_date', time() ); } /** * Handles the AJAX request to retrieve the plugin changelog. * * - Attempts to retrieve the changelog data from a cached transient. * - If no cached data exists, fetches the changelog from the remote API. * - Returns the changelog data as a JSON response. * * @return void */ public function sp_eap_changelog_data() { // Check user capabilities, current_user_can() is called internally. Blocks_Helper::sp_eap_verify_capability(); // Verify nonce. $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, $this->eab_admin_dashboard_nonce_key ) ) { wp_send_json_error( array( 'message' => 'Security check failed.' ), 403 ); return; } $changelog = get_transient( 'sp_ea_changelogs' ); if ( empty( $changelog ) ) { $changelog = $this->eap_fetch_changelog_from_api(); } wp_send_json( array( 'changelog' => $changelog, ) ); } /** * Fetches changelog from the remote API. * Stores the changelog in a transient for caching (1 day). * * @return string The changelog content or empty string on failure. */ protected function eap_fetch_changelog_from_api() { $api_url = 'https://api.wordpress.org/plugins/info/1.0/easy-accordion-free.json'; $response = wp_safe_remote_get( esc_url_raw( $api_url ), array( 'timeout' => 15, ) ); if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { return ''; } $api_data = json_decode( wp_remote_retrieve_body( $response ), true ); if ( ! isset( $api_data['sections']['changelog'] ) ) { return ''; } $changelog = wp_kses_post( $api_data['sections']['changelog'] ); set_transient( 'sp_ea_changelogs', $changelog, DAY_IN_SECONDS ); return $changelog; } /** * Method remove_admin_notices. * * @param object $screen is current screen. * @return void */ public function remove_admin_notices( $screen ) { if ( $screen && 'sp_easy_accordion_page_eap_dashboard' === $screen->id ) { // Disable all other admin notices on this screen. add_action( 'admin_head', function () { remove_all_actions( 'admin_notices' ); remove_all_actions( 'all_admin_notices' ); remove_all_actions( 'network_admin_notices' ); remove_action( 'admin_notices', 'update_nag', 3 ); }, 1 ); } } /** * Method get_dashboard_settings. * * @param string $field_key dashboard settings key name. * @param string $field_default_value dashboard settings default value. * * @return mixed */ public function get_dashboard_settings( $field_key = '', $field_default_value = '' ) { $dashboard_settings = get_option( $this->eap_dashboard_settings_key, array() ); if ( ! empty( $field_key ) ) { $field_value = isset( $dashboard_settings[ $field_key ] ) ? $dashboard_settings[ $field_key ] : $field_default_value; return $field_value; } return $dashboard_settings; } /** * Method update_dashboard_settings. * * @param string $field_key dashboard settings key name. * @param string $field_value dashboard settings value. * * @return void */ private function update_dashboard_settings( $field_key, $field_value ) { $dashboard_settings = $this->get_dashboard_settings(); $dashboard_settings[ $field_key ] = $field_value; update_option( $this->eap_dashboard_settings_key, $dashboard_settings ); } /** * Method init_eap_data_storing. * * @return void */ public function init_eap_data_storing() { $is_user_allow = $this->get_dashboard_settings( 'eap_allow_anonymous_data', false ); if ( $is_user_allow ) { $this->sp_eap_send_data_to_ea_sdr(); } } /** * Handle AJAX request to get and save user consent. * * This function processes user consent preferences for anonymous data sharing. * It requires user authentication and nonce verification for security. * Updates options for setup wizard visit status, anonymous data sharing preference, * Easy Accordion SDR service. * * @return void Sends JSON response with success or error message. */ public function sp_eap_get_user_consent() { // Check user capabilities, current_user_can() is called internally. Blocks_Helper::sp_eap_verify_capability(); // Verify nonce. $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : ''; if ( ! wp_verify_nonce( $nonce, $this->eab_admin_dashboard_nonce_key ) ) { wp_send_json_error( array( 'message' => 'Security check failed.' ), 403 ); return; } // query data. $query_data = isset( $_POST['queryData'] ) ? sanitize_text_field( wp_unslash( $_POST['queryData'] ) ) : ''; $query_data = (array) json_decode( $query_data, true ); // user consent. $allow_anonymous_data = false; $user_consent = $query_data['shareData'] ?? false; if ( $user_consent ) { $allow_anonymous_data = true; $this->sp_eap_send_data_to_ea_sdr(); } // update option data. $this->update_dashboard_settings( 'visited_setup_wizard', true ); $this->update_dashboard_settings( 'eap_allow_anonymous_data', $allow_anonymous_data ); // send response. wp_send_json_success( array( 'message' => 'Successfully done', ) ); } /** * Method sp_eap_send_data_to_ea_sdr. * * It performs nonce verification to ensure the request is legitimate. */ public function sp_eap_send_data_to_ea_sdr() { // ---- Prevent sending data from local/dev sites ---- $site_url = home_url(); $host = wp_parse_url( $site_url, PHP_URL_HOST ); // Check for local sites. if ( 'localhost' === $host || '127.0.0.1' === $host || '::1' === $host || str_ends_with( $host, '.local' ) || str_ends_with( $host, '.test' ) || str_ends_with( $host, '.dev' ) || 1 === preg_match( '/^192\.168\./', $host ) || 1 === preg_match( '/^10\./', $host ) || 1 === preg_match( '/^172\.(1[6-9]|2[0-9]|3[0-1])\./', $host ) ) { return; // Stop here, do not collect or send data. } $theme = wp_get_theme(); // PHP version. $php_version = phpversion(); // Database version. $db_version = get_option( 'easy_accordion_free_db_version' ); $site_language = get_locale(); // Active plugins list. $active_plugins = array(); $plugins = get_plugins(); foreach ( (array) get_option( 'active_plugins', array() ) as $plugin_path ) { if ( isset( $plugins[ $plugin_path ] ) ) { $active_plugins[] = array( 'name' => $plugins[ $plugin_path ]['Name'], 'version' => $plugins[ $plugin_path ]['Version'], ); } } // Get used blocks. $used_blocks = array(); global $wpdb; // Search in posts, pages, custom post types, templates, etc. $post_contents = $wpdb->get_col( $wpdb->prepare( "SELECT post_content FROM {$wpdb->posts} WHERE post_status = 'publish' AND post_content LIKE %s", '%

get_dashboard_settings( 'eap_consent_notice_start_time', null ) ) { $this->update_dashboard_settings( 'eap_consent_notice_start_time', time() ); } } /** * Check whether the consent notice delay period has passed. * * Compares the stored notice start time with the current time * to determine if the specified delay duration has elapsed. * * @param int $days Number of days to wait before showing the notice. * @return bool True if the delay has passed, false otherwise. */ private function eap_has_notice_delay_passed( $days = 7 ) { $start_time = $this->get_dashboard_settings( 'eap_consent_notice_start_time' ); if ( ! $start_time ) { return false; } return ( time() - $start_time ) >= ( DAY_IN_SECONDS * $days ); } /** * Handle user consent submission for anonymous data collection. * * Processes the admin notice form submission, verifies the nonce, * stores the user’s consent choice, and prevents form resubmission * on page refresh. * * @return void */ public function eap_submit_user_consent() { // Handle POST action for the notice buttons. if ( isset( $_POST['eap_anonymous_data_action'] ) && check_admin_referer( 'eap_anonymous_data_action', 'eap_anonymous_data_nonce' ) ) { if ( 'allow' === $_POST['eap_anonymous_data_action'] ) { $this->update_dashboard_settings( 'eap_allow_anonymous_data', true ); } elseif ( 'deny' === $_POST['eap_anonymous_data_action'] ) { $this->update_dashboard_settings( 'eap_ignored_consent_notice', true ); } // Avoid resubmission on refresh. echo ''; exit; } } } }