*/
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' ) . '',
// 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 );
}
}
?>
eab_plugins_info_api_help_page();
?>
'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;
}
}
}
}