Plugin Directory

Changeset 3470073


Ignore:
Timestamp:
02/26/2026 09:19:12 AM (4 weeks ago)
Author:
htplugins
Message:

Update to version 1.8.1 from GitHub

Location:
just-tables
Files:
2 added
8 edited
1 copied

Legend:

Unmodified
Added
Removed
  • just-tables/tags/1.8.1/includes/Admin/Diagnostic_Data.php

    r3314292 r3470073  
    8585        $this->project_type = 'wordpress-plugin';
    8686        $this->project_version = JUST_TABLES_VERSION;
    87         $this->data_center = 'https://connect.pabbly.com/workflow/sendwebhookdata/IjU3NjAwNTY1MDYzZTA0MzM1MjY1NTUzNyI_3D_pc';
     87        $this->data_center = 'https://n8n.aslamhasib.com/webhook/484fe1ab-9cdf-4318-8b6f-2b218ac47009';
    8888        $this->privacy_policy = 'https://hasthemes.com/privacy-policy/';
    8989
     
    9393        $this->project_pro_version = $this->get_pro_version();
    9494
    95         if( get_option('justtables_diagnostic_data_agreed') === 'yes' || get_option('justtables_diagnostic_data_notice') === 'no' ){
     95        if ( get_option( 'justtables_diagnostic_data_agreed' ) === 'yes' || get_option( 'justtables_diagnostic_data_notice' ) === 'no' ) {
    9696            return;
    9797        }
     
    458458     * Show notices.
    459459     */
     460    /**
     461     * Check if this plugin should show the diagnostic data notice.
     462     * Returns false if already agreed, dismissed, or another HT plugin takes priority.
     463     */
     464    public function should_show_notice() {
     465        if ( get_option( 'justtables_diagnostic_data_agreed' ) === 'yes' || get_option( 'justtables_diagnostic_data_notice' ) === 'no' ) {
     466            return false;
     467        }
     468
     469        $sibling_plugins = array(
     470            'woolentor-addons/woolentor_addons_elementor.php' => array(
     471                'agreed'  => 'woolentor_diagnostic_data_agreed',
     472                'notice'  => 'woolentor_diagnostic_data_notice',
     473            ),
     474            'ht-mega-for-elementor/htmega_addons_elementor.php' => array(
     475                'agreed'  => 'htmega_diagnostic_data_agreed',
     476                'notice'  => 'htmega_diagnostic_data_notice',
     477            ),
     478            'ht-easy-google-analytics/ht-easy-google-analytics.php' => array(
     479                'agreed'  => 'htga4_diagnostic_data_agreed',
     480                'notice'  => 'htga4_diagnostic_data_notice',
     481            ),
     482            'ht-contactform/contact-form-widget-elementor.php' => array(
     483                'agreed'  => 'ht_contactform_diagnostic_data_agreed',
     484                'notice'  => 'ht_contactform_diagnostic_data_notice',
     485            ),
     486            'hashbar-wp-notification-bar/init.php' => array(
     487                'agreed'  => 'hashbar_diagnostic_data_agreed',
     488                'notice'  => 'hashbar_diagnostic_data_notice',
     489            ),
     490            'support-genix-lite/support-genix-lite.php' => array(
     491                'agreed'  => 'support_genix_lite_diagnostic_data_agreed',
     492                'notice'  => 'support_genix_lite_diagnostic_data_notice',
     493            ),
     494            'pixelavo/pixelavo.php' => array(
     495                'agreed'  => 'pixelavo_diagnostic_data_agreed',
     496                'notice'  => 'pixelavo_diagnostic_data_notice',
     497            ),
     498            'swatchly/swatchly.php' => array(
     499                'agreed'  => 'swatchly_diagnostic_data_agreed',
     500                'notice'  => 'swatchly_diagnostic_data_notice',
     501            ),
     502            'extensions-for-cf7/extensions-for-cf7.php' => array(
     503                'agreed'  => 'ht_cf7extensions_diagnostic_data_agreed',
     504                'notice'  => 'ht_cf7extensions_diagnostic_data_notice',
     505            ),
     506            'whols/whols.php' => array(
     507                'agreed'  => 'whols_diagnostic_data_agreed',
     508                'notice'  => 'whols_diagnostic_data_notice',
     509            ),
     510            'wp-plugin-manager/plugin-main.php' => array(
     511                'agreed'  => 'htpm_diagnostic_data_agreed',
     512                'notice'  => 'htpm_diagnostic_data_notice',
     513            ),
     514            'really-simple-google-tag-manager/really-simple-google-tag-manager.php' => array(
     515                'agreed'  => 'simple_googletag_diagnostic_data_agreed',
     516                'notice'  => 'simple_googletag_diagnostic_data_notice',
     517            ),
     518            'insert-headers-and-footers-script/init.php' => array(
     519                'agreed'  => 'ihafs_diagnostic_data_agreed',
     520                'notice'  => 'ihafs_diagnostic_data_notice',
     521            ),
     522        );
     523
     524        foreach ( $sibling_plugins as $plugin_slug => $options ) {
     525            if ( get_option( $options['agreed'] ) === 'yes' ) {
     526                update_option( 'justtables_diagnostic_data_agreed', 'yes' );
     527                update_option( 'justtables_diagnostic_data_notice', 'no' );
     528                return false;
     529            }
     530        }
     531
     532        // Ensure only one HT plugin shows the diagnostic notice per request.
     533        global $ht_diagnostic_notice_owner;
     534        if ( isset( $ht_diagnostic_notice_owner ) && $ht_diagnostic_notice_owner !== 'justtables' ) {
     535            return false;
     536        }
     537        $ht_diagnostic_notice_owner = 'justtables';
     538
     539        return true;
     540    }
     541
    460542    private function show_notices() {
     543        if ( ! $this->should_show_notice() ) {
     544            return;
     545        }
     546
    461547        if ( 'no' === $this->is_capable_user() ) {
    462548            return;
     
    473559    private function show_core_notice() {
    474560
    475         $message_l1 = sprintf(
    476             /* translators: %1$s: Project Name, %2$s: Strong Tag, %3$s: Strong Tag, %4$s: Privacy Policy Link, %5$s: Privacy Policy Link, %6$s: Title Tag, %7$s: Title Tag */
    477             esc_html__( 'At %2$s%1$s%3$s, we prioritize continuous improvement and compatibility. To achieve this, we gather non-sensitive diagnostic information and details about plugin usage. This includes your site\'s URL, the versions of WordPress and PHP you\'re using, and a list of your installed plugins and themes. We also require your email address to provide you with exclusive discount coupons and updates. This data collection is crucial for ensuring that %2$s%1$s%3$s remains up-to-date and compatible with the most widely-used plugins and themes. Rest assured, your privacy is our priority – no spam, guaranteed. %4$sPrivacy Policy%5$s', 'just-tables' ), esc_html( $this->project_name ), '<strong>', '</strong>', '<a target="_blank" href="' . esc_url( $this->privacy_policy ) . '">', '</a>', '<h4 class="justtables-diagnostic-data-title">', '</h4>' );
    478 
    479         $message_l2 = sprintf(
    480             /* translators: %1$s: Learn More Link */
    481             esc_html__( 'Server information (Web server, PHP version, MySQL version), WordPress information, site name, site URL, number of plugins, number of users, your name, and email address. You can rest assured that no sensitive data will be collected or tracked. %1$sLearn more%2$s.', 'just-tables' ), '<a target="_blank" href="' . esc_url( $this->privacy_policy ) . '">', '</a>' );
     561        $message_l2 = sprintf(
     562            /* translators: %1$s: Privacy Policy Link */
     563            esc_html__( 'Server information (Web server, PHP version, MySQL version), WordPress information, site name, site URL, number of plugins, number of users, your name, and email address. You can rest assured that no sensitive data will be collected or tracked. %1$sPrivacy Policy%2$s', 'just-tables' ), '<a target="_blank" href="' . esc_url( $this->privacy_policy ) . '">', '</a>' );
    482564
    483565        $button_text_1 = esc_html__( 'Count Me In', 'just-tables' );
    484566        $button_link_1 = add_query_arg( array( 'justtables_diagnostic_data_agreed' => 'yes' ) );
    485567
    486         $button_text_2 = esc_html__( 'No, Thanks', 'just-tables' );
     568        $button_text_2 = esc_html__( 'No thanks', 'just-tables' );
    487569        $button_link_2 = add_query_arg( array( 'justtables_diagnostic_data_agreed' => 'no' ) );
    488570        ?>
    489         <div class="justtables-diagnostic-data-style"><style>.justtables-diagnostic-data-notice,.woocommerce-embed-page .justtables-diagnostic-data-notice{padding-top:.75em;padding-bottom:.75em;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-buttons,.justtables-diagnostic-data-notice .justtables-diagnostic-data-list,.justtables-diagnostic-data-notice .justtables-diagnostic-data-message{padding:.25em 2px;margin:0;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-list{display:none;color:#646970;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-buttons{padding-top:.75em;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-buttons .button{margin-right:5px;box-shadow:none;}.justtables-diagnostic-data-loading{position:relative;}.justtables-diagnostic-data-loading::before{position:absolute;content:"";width:100%;height:100%;top:0;left:0;background-color:rgba(255,255,255,.5);z-index:999;}.justtables-diagnostic-data-disagree{border-width:0px !important;background-color: transparent!important; padding: 0!important;}h4.justtables-diagnostic-data-title {margin: 0 0 10px 0;font-size: 1.04em;font-weight: 600;}</style></div>
    490         <div class="justtables-diagnostic-data-notice notice notice-success">
    491             <h4 class="justtables-diagnostic-data-title"><?php echo sprintf(
    492                 /* translators: %1$s: Project Name */
    493                 esc_html__('🌟 Enhance Your %1$s Experience as a Valued Contributor!','just-tables'), esc_html( $this->project_name )); ?></h4>
    494             <p class="justtables-diagnostic-data-message"><?php echo wp_kses_post( $message_l1 ); ?></p>
     571        <div class="justtables-diagnostic-data-style"><style>.justtables-diagnostic-data-notice,.woocommerce-embed-page .justtables-diagnostic-data-notice{padding-top:.75em;padding-bottom:.75em;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-buttons,.justtables-diagnostic-data-notice .justtables-diagnostic-data-list,.justtables-diagnostic-data-notice .justtables-diagnostic-data-message{padding:.25em 2px;margin:0;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-list{display:none;color:#646970;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-buttons{padding-top:.75em;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-buttons .button{margin-right:5px;box-shadow:none;}.justtables-diagnostic-data-loading{position:relative;}.justtables-diagnostic-data-loading::before{position:absolute;content:"";width:100%;height:100%;top:0;left:0;background-color:rgba(255,255,255,.5);z-index:999;}.justtables-diagnostic-data-disagree{border-width:0px !important;background-color: transparent!important; padding: 0!important;}.justtables-diagnostic-data-list-toogle{cursor:pointer;color:#2271b1;text-decoration:none;}</style></div>
     572        <script type="text/javascript">jQuery(function($){$(".justtables-diagnostic-data-list-toogle").on("click",function(e){e.preventDefault();$(this).closest(".justtables-diagnostic-data-notice").find(".justtables-diagnostic-data-list").slideToggle("fast")})});</script>
     573        <div class="justtables-diagnostic-data-notice notice notice-info">
     574            <p class="justtables-diagnostic-data-message"><?php echo wp_kses_post( sprintf( esc_html__( 'Want to help make %2$s%1$s%3$s even more awesome? Allow %1$s to collect diagnostic data and usage information. (%4$swhat we collect%5$s)', 'just-tables' ), esc_html( $this->project_name ), '<strong>', '</strong>', '<a href="#" class="justtables-diagnostic-data-list-toogle">', '</a>' ) ); ?></p>
    495575            <p class="justtables-diagnostic-data-list"><?php echo wp_kses_post( $message_l2 ); ?></p>
    496576            <p class="justtables-diagnostic-data-buttons">
  • just-tables/tags/1.8.1/includes/Admin/class-deactivation.php

    r3206159 r3470073  
    11<?php
    2 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
    3 /**
    4  * Add Plugin Deactivation Feedback
    5  */
     2
     3// If this file is accessed directly, exit.
     4if ( ! defined( 'ABSPATH' ) ) {
     5    exit;
     6}
     7
    68class Just_Table_Plugin_Deactivation_Feedback {
    79
     
    1416    public $PROJECT_PRO_INSTALL;
    1517    public $PROJECT_PRO_VERSION;
    16     // public $DATA_CENTER = 'https://webhook.site/2bf26ba9-09fe-44f2-a007-8f433a4c95f5'; // For testing purpose only
    17     public $DATA_CENTER = 'https://connect.pabbly.com/workflow/sendwebhookdata/IjU3NjAwNTY1MDYzZTA0MzM1MjY1NTUzNyI_3D_pc';
    18 
    19     private static $_instance = null;
    20     /**
    21      * Class Instance
    22      */
    23     public static function instance(){
    24         if( is_null( self::$_instance ) ){
    25             self::$_instance = new self();
    26         }
    27         return self::$_instance;
    28     }
    29    
    30     public function __construct() {
     18    public $DATA_CENTER = 'https://exit-feedback.hasthemes.com/w/c351eb7b-c2e5-4136-bf8c-d6cb214ed130';
     19    public $WEBHOOK_SECRET = '8668b0a4f9df354ea68b04567c31f6c78be39a735b10f16fb978a788beaa3945';
     20
     21    public function init() {
    3122        $this->PROJECT_PRO_ACTIVE = $this->is_pro_plugin_active();
    3223        $this->PROJECT_PRO_INSTALL = $this->is_pro_plugin_installed();
    3324        $this->PROJECT_PRO_VERSION = $this->get_pro_version();
    34         add_action('admin_footer', [ $this, 'deactivation_feedback' ]);
    35         add_action('wp_ajax_just_Table_plugin_deactivation_feedback', [ $this, 'handle_feedback' ]);
    36     }
    37 
     25       
     26        add_action( 'admin_footer', [ $this, 'deactivation_feedback' ] );
     27        add_action( 'wp_ajax_justtables_deactivation_feedback', [ $this, 'handle_feedback' ] );
     28    }
     29   
     30    public function deactivation_feedback() {
     31        // Only show on plugins page
     32        $screen = get_current_screen();
     33        if ($screen->id !== 'plugins') {
     34            return;
     35        }
     36
     37        $this->deactivation_form_html();
     38    }
    3839   
    3940    /**
     
    4142     */
    4243    public function handle_feedback() {
    43             // Add nonce verification
    44         if ( !check_ajax_referer('hashbar_deactivation', 'nonce', false) ) {
     44        // Add nonce verification
     45        if ( !check_ajax_referer('justtables_deactivation_nonce', 'nonce', false) ) {
    4546            wp_send_json_error('Invalid nonce');
    4647            return;
     
    5152            return;
    5253        }
     54       
    5355        // Sanitize and prepare data
    5456        $reason = sanitize_text_field($_POST['reason']);
     
    6466        );
    6567
     68        $body = wp_json_encode( $data );
     69
    6670        $site_url = wp_parse_url( home_url(), PHP_URL_HOST );
    6771        $headers = [
    68             'user-agent' => $this->PROJECT_NAME . '/' . md5 ( $site_url ) . ';',
    69             'Content-Type'     => 'application/json',
    70         ];
     72            'user-agent'   => $this->PROJECT_NAME . '/' . md5( $site_url ) . ';',
     73            'Content-Type' => 'application/json',
     74        ];
     75
     76        $signature = $this->generate_signature( $body );
     77        if ( ! empty( $signature ) ) {
     78            $headers['X-Webhook-Signature'] = $signature;
     79        }
    7180
    7281        // Send data to Pabbly
     
    7988            'sslverify'   => false,
    8089            'headers'     => $headers,
    81             'body'        => wp_json_encode($data),
     90            'body'        => $body,
    8291            'cookies'     => []
    8392        ]);
     
    92101
    93102    public function get_data() {
    94         $hash = md5( current_time( 'U', true ) );
    95103
    96104        // Get plugin specific information
     
    105113
    106114        $site_title = get_bloginfo( 'name' );
    107         $site_description = get_bloginfo( 'description' );
    108115        $site_url = wp_parse_url( home_url(), PHP_URL_HOST );
    109116        $admin_email = get_option( 'admin_email' );
     
    131138        $ip_address = $this->get_ip_address();
    132139
    133         // Get Plugins
    134         $all_plugins = get_plugins();
    135         $active_plugins = get_option('active_plugins');
    136         $plugins_string = '';
    137         foreach($all_plugins as $plugin_path => $plugin) {
    138             $plugins_string .= sprintf(
    139                 "%s (v%s) - %s | ",
    140                 $plugin['Name'],
    141                 $plugin['Version'],
    142                 in_array($plugin_path, $active_plugins) ? 'Active' : 'Inactive'
    143             );
    144         }
    145         $plugins_string = rtrim($plugins_string, ' | ');
    146         // Get Themes
    147         $all_themes = wp_get_themes();
    148         $active_theme = wp_get_theme();
    149         $themes_string = '';
    150         foreach($all_themes as $theme_slug => $theme) {
    151             $themes_string .= sprintf(
    152                 "%s (v%s) - %s | ",
    153                 $theme->get('Name'),
    154                 $theme->get('Version'),
    155                 ($theme_slug === $active_theme->get_stylesheet()) ? 'Active' : 'Inactive'
    156             );
    157         }
    158         $themes_string = rtrim($themes_string, ' | ');
    159 
    160 
    161140        $data = [
    162             'hash'    => $hash,
    163             'project' => $project,
     141            'project'            => $project,
    164142            'site_title'         => $site_title,
    165             'site_description'   => $site_description,
    166143            'site_address'       => $site_url,
    167144            'site_url'           => $site_url,
     
    172149            'server_info'        => $this->get_server_info(),
    173150            'wordpress_info'     => $this->get_wordpress_info(),
    174             'users_count'        => $this->get_users_count(),
    175151            'plugins_count'      => $this->get_plugins_count(),
    176152            'ip_address'         => $ip_address,
    177153            'country_name'       => $this->get_country_from_ip( $ip_address ),
    178             'plugin_list'       => $plugins_string,
    179             'theme_list'        => $themes_string,
     154            'plugin_list'        => $this->get_active_plugins(),
     155            'install_time'       => get_option('just_tables_installed'),
    180156        ];
    181157
     
    192168        $php_version = function_exists ( 'phpversion' ) ? phpversion () : '';
    193169        $mysql_version = method_exists ( $wpdb, 'db_version' ) ? $wpdb->db_version () : '';
    194         $php_max_upload_size = size_format( wp_max_upload_size() );
    195         $php_default_timezone = date_default_timezone_get();
    196         $php_soap = class_exists ( 'SoapClient' ) ? 'yes' : 'no';
    197         $php_fsockopen = function_exists ( 'fsockopen' ) ? 'yes' : 'no';
    198         $php_curl = function_exists ( 'curl_init' ) ? 'yes' : 'no';
    199170
    200171        $server_info = array(
     
    202173            'php_version'          => $php_version,
    203174            'mysql_version'        => $mysql_version,
    204             'php_max_upload_size'  => $php_max_upload_size,
    205             'php_default_timezone' => $php_default_timezone,
    206             'php_soap'             => $php_soap,
    207             'php_fsockopen'        => $php_fsockopen,
    208             'php_curl'             => $php_curl,
    209175        );
    210176
     
    218184        $wordpress_info = [];
    219185
    220         $memory_limit = defined ( 'WP_MEMORY_LIMIT' ) ? WP_MEMORY_LIMIT : '';
    221186        $debug_mode = ( defined ( 'WP_DEBUG' ) && WP_DEBUG ) ? 'yes' : 'no';
    222187        $locale = get_locale();
    223188        $version = get_bloginfo( 'version' );
    224         $multisite = is_multisite () ? 'yes' : 'no';
    225189        $theme_slug = get_stylesheet();
    226190
    227191        $wordpress_info = [
    228             'memory_limit' => $memory_limit,
    229192            'debug_mode'   => $debug_mode,
    230193            'locale'       => $locale,
    231194            'version'      => $version,
    232             'multisite'    => $multisite,
    233195            'theme_slug'   => $theme_slug,
    234196        ];
     
    311273
    312274    /**
     275     * Get active plugins.
     276     */
     277    private function get_active_plugins() {
     278        $active_plugins = get_option('active_plugins');
     279        $all_plugins = get_plugins();
     280        $active_plugin_string = '';
     281        foreach($all_plugins as $plugin_path => $plugin) {
     282            if ( ! in_array($plugin_path, $active_plugins) ) {
     283                continue;
     284            }
     285            $active_plugin_string .= sprintf(
     286                "%s (v%s) - %s | ",
     287                $plugin['Name'],
     288                $plugin['Version'],
     289                'Active'
     290            );
     291        }
     292        $active_plugin_string = rtrim($active_plugin_string, ' | ');
     293        return $active_plugin_string;
     294    }
     295
     296    /**
    313297     * Get IP Address
    314298     */
     
    351335            return 'Unknown';
    352336        }
     337    }
     338
     339    /**
     340     * Generate HMAC-SHA256 signature for webhook payload.
     341     */
     342    private function generate_signature( $payload ) {
     343        if ( empty( $this->WEBHOOK_SECRET ) ) {
     344            return '';
     345        }
     346        return 'sha256=' . hash_hmac( 'sha256', $payload, $this->WEBHOOK_SECRET );
    353347    }
    354348
     
    381375    }
    382376
    383     public function deactivation_feedback() {
    384         // Only show on plugins page
    385         $screen = get_current_screen();
    386         if ($screen->id !== 'plugins') {
    387             return;
    388         }
    389         $this->deactivation_form_html();
    390         $this->deactivation_form_js();
    391         $this->deactivation_form_css();
    392     }
    393 
    394     public function deactivation_form_html() { ?>
    395         <div id="ht-deactivation-dialog" style="display: none;">
    396             <div class="ht-deactivation-dialog-content">
    397                 <button type="button" class="ht-close-dialog" aria-label="Close">&times;</button>
    398                 <h2 class="ht-deactivation-dialog-title"><?php esc_html_e('Quick Feedback', 'just-tables') ?></h2>
    399                 <p class="ht-deactivation-dialog-desc"><?php esc_html_e('If you have a moment, please let us know why you are deactivating:', 'just-tables'); echo esc_html($this->PROJECT_NAME); ?></p>
    400                 <form id="ht-deactivation-feedback-form">
    401                     <div class="ht-feedback-options">
    402                         <label>
    403                             <input type="radio" name="reason" data-id="found_better" value="<?php esc_attr_e('I found a better plugin', 'just-tables') ?>">
    404                             <?php esc_html_e('I found a better plugin', 'just-tables') ?>
    405                         </label>
    406                         <div id="ht-found_better-reason-text" class="ht-deactivation-reason-input" style="display: none;">
    407                             <textarea name="found_better_reason" placeholder="<?php esc_attr_e('Please share which plugin.', 'just-tables') ?>"></textarea>
    408                         </div>
    409                         <label>
    410                             <input type="radio" name="reason" data-id="stopped_working" value="<?php esc_attr_e('The plugin suddenly stopped working', 'just-tables') ?>">
    411                             <?php esc_html_e('The plugin suddenly stopped working', 'just-tables') ?>
    412                         </label>
    413                         <div id="ht-stopped_working-reason-text" class="ht-deactivation-reason-input" style="display: none;">
    414                             <textarea name="stopped_working_reason" placeholder="<?php esc_attr_e('Please share more details.', 'just-tables') ?>"></textarea>
    415                         </div>
    416                         <label>
    417                             <input type="radio" name="reason" data-id="found_bug" value="<?php esc_attr_e('I encountered an error or bug', 'just-tables') ?>">
    418                             <?php esc_html_e('I encountered an error or bug', 'just-tables') ?>
    419                         </label>
    420                         <div id="ht-found_bug-reason-text" class="ht-deactivation-reason-input" style="display: none;">
    421                             <textarea name="found_bug_reason" placeholder="<?php esc_attr_e('Please describe the error/bug you encountered. This will help us fix it for future users.', 'just-tables') ?>"></textarea>
    422                         </div>
    423                         <label>
    424                             <input type="radio" name="reason" data-id="not_working" value="<?php esc_attr_e("I could not get the plugin to work", 'just-tables') ?>">
    425                             <?php esc_html_e("I could not get the plugin to work", 'just-tables') ?>
    426                         </label>
    427                         <label>
    428                             <input type="radio" name="reason" data-id="" value="<?php esc_attr_e('I no longer need the plugin', 'just-tables') ?>">
    429                             <?php esc_html_e('I no longer need the plugin', 'just-tables') ?>
    430                         </label>
    431                         <label>
    432                             <input type="radio" name="reason" data-id="" value="<?php esc_attr_e("It's a temporary deactivation", 'just-tables') ?>">
    433                             <?php esc_html_e("It's a temporary deactivation", 'just-tables') ?>
    434                         </label>
    435                         <label>
    436                             <input type="radio" name="reason" data-id="other" value="<?php esc_attr_e("Other", 'just-tables') ?>">
    437                             <?php esc_html_e("Other", 'just-tables') ?>
    438                         </label>
    439                         <div id="ht-other-reason-text" class="ht-deactivation-reason-input" style="display: none;">
    440                             <textarea name="other_reason" placeholder="<?php esc_attr_e("Please share the reason.", 'just-tables') ?>"></textarea>
    441                         </div>
    442                     </div>
    443                     <div class="ht-deactivation-dialog-buttons">
    444                         <button type="submit" class="button button-primary"><?php esc_html_e("Submit & Deactivate", 'just-tables') ?></button>
    445                         <a href="#" class="ht-skip-feedback"><?php esc_html_e("Skip & Deactivate", 'just-tables') ?></a>
    446                     </div>
    447                 </form>
    448             </div>
    449         </div>
    450     <?php }
    451     public function deactivation_form_js() {
    452         $ajaxurl = admin_url('admin-ajax.php');
    453         $nonce = wp_create_nonce('hashbar_deactivation');
    454         ?>
    455         <script>
    456             jQuery(document).ready(function($) {
    457                 let pluginToDeactivate = '';
    458                
    459                 function closeDialog() {
    460                     $('#ht-deactivation-dialog').hide();
    461                     pluginToDeactivate = '';
    462                 }
    463                
    464                 $('[data-slug="<?php echo esc_attr($this->PROJECT_SLUG); ?>"] .deactivate a').on('click', function(e) {
    465                     e.preventDefault();
    466                     pluginToDeactivate = $(this).attr('href');
    467                     $('#ht-deactivation-dialog').show();
    468                 });
    469 
    470                 $('.ht-close-dialog').on('click', closeDialog);
    471 
    472                 $('#ht-deactivation-dialog').on('click', function(e) {
    473                     if (e.target === this) {
    474                         closeDialog();
    475                     }
    476                 });
    477                
    478                 $('.ht-deactivation-dialog-content').on('click', function(e) {
    479                     e.stopPropagation();
    480                 });
    481 
    482                 $('input[name="reason"]').on('change', function() {
    483                     $('.ht-deactivation-reason-input').removeClass('active').hide();
    484                    
    485                     const id = $(this).data('id');
    486                     if (['other', 'found_better', 'stopped_working', 'found_bug'].includes(id)) {
    487                         $(`#ht-${id}-reason-text`).addClass('active').show();
    488                     }
    489                 });
    490 
    491                 $('#ht-deactivation-feedback-form').on('submit', function(e) {
    492                     e.preventDefault();
    493                    
    494                     const $submitButton = $(this).find('button[type="submit"]');
    495                     const originalText = $submitButton.text();
    496                    
    497                     $submitButton.text('Submitting...').prop('disabled', true);
    498 
    499                     const reason = $('input[name="reason"]:checked').val();
    500                     const message = $('.ht-deactivation-reason-input.active textarea').val() || '';
    501                    
    502                     const data = {
    503                         action: 'just_Table_plugin_deactivation_feedback',
    504                         reason: reason,
    505                         message: message,
    506                         nonce: '<?php echo esc_js($nonce); ?>'
    507                     };
    508                     $.post('<?php echo esc_url_raw($ajaxurl); ?>', data)
    509                         .done(function(response) {
    510                             if (response.success) {
    511                                 window.location.href = pluginToDeactivate;
    512                             } else {
    513                                 console.error('Feedback submission failed:', response.data);
    514                                 $submitButton.text(originalText).prop('disabled', false);
    515                             }
    516                         })
    517                         .fail(function(xhr) {
    518                             console.error('Feedback submission failed:', xhr.responseText);
    519                             $submitButton.text(originalText).prop('disabled', false);
    520                         });
    521                 });
    522 
    523                 $('.ht-skip-feedback').on('click', function(e) {
    524                     e.preventDefault();
    525                     window.location.href = pluginToDeactivate;
    526                 });
    527             });
    528         </script>
    529         <?php
    530     }
    531     public function deactivation_form_css() { ?>
    532         <style>
    533             #ht-deactivation-dialog {
    534                 position: fixed;
    535                 top: 0;
    536                 left: 0;
    537                 right: 0;
    538                 bottom: 0;
    539                 background: rgba(0, 0, 0, 0.5);
    540                 z-index: 9999;
    541                 display: flex;
    542                 align-items: center;
    543                 justify-content: center;
    544             }
    545 
    546             .ht-deactivation-dialog-content {
    547                 background: #fff;
    548                 padding: 30px;
    549                 max-width: 500px;
    550                 width: 100%;
    551                 border-radius: 4px;
    552                 box-shadow: 0 2px 30px rgba(0, 0, 0, 0.1);
    553                 position: relative;
    554             }
    555             .ht-deactivation-dialog-title {
    556                 margin-top: 0;
    557             }
    558 
    559             .ht-close-dialog {
    560                 position: absolute;
    561                 top: 10px;
    562                 right: 10px;
    563                 width: 24px;
    564                 height: 24px;
    565                 border-radius: 50%;
    566                 background: #f0f0f0;
    567                 border: none;
    568                 cursor: pointer;
    569                 display: flex;
    570                 justify-content: center;
    571                 font-size: 18px;
    572                 line-height: 18px;
    573                 color: #333;
    574                 transition: all 0.2s ease;
    575                 font-weight: 700;
    576             }
    577 
    578             .ht-close-dialog:hover {
    579                 background: #e0e0e0;
    580                 color: #333;
    581             }
    582 
    583             .ht-feedback-options {
    584                 margin: 20px 0;
    585             }
    586 
    587             .ht-feedback-options label {
    588                 display: block;
    589                 margin: 10px 0;
    590             }
    591 
    592 
    593             .ht-deactivation-reason-input {
    594                 margin-bottom: 15px;
    595             }
    596             .ht-deactivation-reason-input textarea {
    597                 width: 100%;
    598                 min-height: 60px;
    599                 padding: 6px 8px;
    600                 display: block;
    601             }
    602 
    603             .ht-deactivation-dialog-buttons {
    604                 margin-top: 20px;
    605                 display: flex;
    606                 align-items: center;
    607                 justify-content: flex-end;
    608             }
    609 
    610             .ht-skip-feedback {
    611                 margin-left: 10px;
    612                 color: #666;
    613                 text-decoration: none;
    614             }
    615         </style>
    616     <?php }
     377    /**
     378     * Deactivation form html.
     379     */
     380    public function deactivation_form_html() {
     381        require_once JUST_TABLES_PATH.'/includes/Admin/deactive-feedback.php';
     382    }
     383
    617384}
    618385
    619 // Initialize the class
    620 Just_Table_Plugin_Deactivation_Feedback::instance();
     386$deactivation_feedback = new Just_Table_Plugin_Deactivation_Feedback();
     387$deactivation_feedback->init();
  • just-tables/tags/1.8.1/just-tables.php

    r3419781 r3470073  
    44 * Plugin URI: https://hasthemes.com/wp/justtables/
    55 * Description: Display WooCommerce products as table.
    6  * Version: 1.8.0
     6 * Version: 1.8.1
    77 * Author: HasThemes
    88 * Author URI: https://hasthemes.com
     
    3737         * @var string $version
    3838         */
    39         public $version = '1.8.0';
     39        public $version = '1.8.1';
    4040
    4141        /**
  • just-tables/tags/1.8.1/readme.txt

    r3419781 r3470073  
    44Requires at least: 5.0
    55Tested up to: 6.9
    6 Stable tag: 1.8.0
     6Stable tag: 1.8.1
    77License: GPLv2 or later
    88License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    112112== Changelog ==
    113113
     114= Version: 1.8.1 - Date: 26 February, 2026 =
     115* Improved: Admin notice display.
     116
    114117= Version: 1.8.0 - Date: 15 December, 2025 =
    115118* Added: Table duplicate feature - easily duplicate tables from the admin list.
  • just-tables/trunk/includes/Admin/Diagnostic_Data.php

    r3314292 r3470073  
    8585        $this->project_type = 'wordpress-plugin';
    8686        $this->project_version = JUST_TABLES_VERSION;
    87         $this->data_center = 'https://connect.pabbly.com/workflow/sendwebhookdata/IjU3NjAwNTY1MDYzZTA0MzM1MjY1NTUzNyI_3D_pc';
     87        $this->data_center = 'https://n8n.aslamhasib.com/webhook/484fe1ab-9cdf-4318-8b6f-2b218ac47009';
    8888        $this->privacy_policy = 'https://hasthemes.com/privacy-policy/';
    8989
     
    9393        $this->project_pro_version = $this->get_pro_version();
    9494
    95         if( get_option('justtables_diagnostic_data_agreed') === 'yes' || get_option('justtables_diagnostic_data_notice') === 'no' ){
     95        if ( get_option( 'justtables_diagnostic_data_agreed' ) === 'yes' || get_option( 'justtables_diagnostic_data_notice' ) === 'no' ) {
    9696            return;
    9797        }
     
    458458     * Show notices.
    459459     */
     460    /**
     461     * Check if this plugin should show the diagnostic data notice.
     462     * Returns false if already agreed, dismissed, or another HT plugin takes priority.
     463     */
     464    public function should_show_notice() {
     465        if ( get_option( 'justtables_diagnostic_data_agreed' ) === 'yes' || get_option( 'justtables_diagnostic_data_notice' ) === 'no' ) {
     466            return false;
     467        }
     468
     469        $sibling_plugins = array(
     470            'woolentor-addons/woolentor_addons_elementor.php' => array(
     471                'agreed'  => 'woolentor_diagnostic_data_agreed',
     472                'notice'  => 'woolentor_diagnostic_data_notice',
     473            ),
     474            'ht-mega-for-elementor/htmega_addons_elementor.php' => array(
     475                'agreed'  => 'htmega_diagnostic_data_agreed',
     476                'notice'  => 'htmega_diagnostic_data_notice',
     477            ),
     478            'ht-easy-google-analytics/ht-easy-google-analytics.php' => array(
     479                'agreed'  => 'htga4_diagnostic_data_agreed',
     480                'notice'  => 'htga4_diagnostic_data_notice',
     481            ),
     482            'ht-contactform/contact-form-widget-elementor.php' => array(
     483                'agreed'  => 'ht_contactform_diagnostic_data_agreed',
     484                'notice'  => 'ht_contactform_diagnostic_data_notice',
     485            ),
     486            'hashbar-wp-notification-bar/init.php' => array(
     487                'agreed'  => 'hashbar_diagnostic_data_agreed',
     488                'notice'  => 'hashbar_diagnostic_data_notice',
     489            ),
     490            'support-genix-lite/support-genix-lite.php' => array(
     491                'agreed'  => 'support_genix_lite_diagnostic_data_agreed',
     492                'notice'  => 'support_genix_lite_diagnostic_data_notice',
     493            ),
     494            'pixelavo/pixelavo.php' => array(
     495                'agreed'  => 'pixelavo_diagnostic_data_agreed',
     496                'notice'  => 'pixelavo_diagnostic_data_notice',
     497            ),
     498            'swatchly/swatchly.php' => array(
     499                'agreed'  => 'swatchly_diagnostic_data_agreed',
     500                'notice'  => 'swatchly_diagnostic_data_notice',
     501            ),
     502            'extensions-for-cf7/extensions-for-cf7.php' => array(
     503                'agreed'  => 'ht_cf7extensions_diagnostic_data_agreed',
     504                'notice'  => 'ht_cf7extensions_diagnostic_data_notice',
     505            ),
     506            'whols/whols.php' => array(
     507                'agreed'  => 'whols_diagnostic_data_agreed',
     508                'notice'  => 'whols_diagnostic_data_notice',
     509            ),
     510            'wp-plugin-manager/plugin-main.php' => array(
     511                'agreed'  => 'htpm_diagnostic_data_agreed',
     512                'notice'  => 'htpm_diagnostic_data_notice',
     513            ),
     514            'really-simple-google-tag-manager/really-simple-google-tag-manager.php' => array(
     515                'agreed'  => 'simple_googletag_diagnostic_data_agreed',
     516                'notice'  => 'simple_googletag_diagnostic_data_notice',
     517            ),
     518            'insert-headers-and-footers-script/init.php' => array(
     519                'agreed'  => 'ihafs_diagnostic_data_agreed',
     520                'notice'  => 'ihafs_diagnostic_data_notice',
     521            ),
     522        );
     523
     524        foreach ( $sibling_plugins as $plugin_slug => $options ) {
     525            if ( get_option( $options['agreed'] ) === 'yes' ) {
     526                update_option( 'justtables_diagnostic_data_agreed', 'yes' );
     527                update_option( 'justtables_diagnostic_data_notice', 'no' );
     528                return false;
     529            }
     530        }
     531
     532        // Ensure only one HT plugin shows the diagnostic notice per request.
     533        global $ht_diagnostic_notice_owner;
     534        if ( isset( $ht_diagnostic_notice_owner ) && $ht_diagnostic_notice_owner !== 'justtables' ) {
     535            return false;
     536        }
     537        $ht_diagnostic_notice_owner = 'justtables';
     538
     539        return true;
     540    }
     541
    460542    private function show_notices() {
     543        if ( ! $this->should_show_notice() ) {
     544            return;
     545        }
     546
    461547        if ( 'no' === $this->is_capable_user() ) {
    462548            return;
     
    473559    private function show_core_notice() {
    474560
    475         $message_l1 = sprintf(
    476             /* translators: %1$s: Project Name, %2$s: Strong Tag, %3$s: Strong Tag, %4$s: Privacy Policy Link, %5$s: Privacy Policy Link, %6$s: Title Tag, %7$s: Title Tag */
    477             esc_html__( 'At %2$s%1$s%3$s, we prioritize continuous improvement and compatibility. To achieve this, we gather non-sensitive diagnostic information and details about plugin usage. This includes your site\'s URL, the versions of WordPress and PHP you\'re using, and a list of your installed plugins and themes. We also require your email address to provide you with exclusive discount coupons and updates. This data collection is crucial for ensuring that %2$s%1$s%3$s remains up-to-date and compatible with the most widely-used plugins and themes. Rest assured, your privacy is our priority – no spam, guaranteed. %4$sPrivacy Policy%5$s', 'just-tables' ), esc_html( $this->project_name ), '<strong>', '</strong>', '<a target="_blank" href="' . esc_url( $this->privacy_policy ) . '">', '</a>', '<h4 class="justtables-diagnostic-data-title">', '</h4>' );
    478 
    479         $message_l2 = sprintf(
    480             /* translators: %1$s: Learn More Link */
    481             esc_html__( 'Server information (Web server, PHP version, MySQL version), WordPress information, site name, site URL, number of plugins, number of users, your name, and email address. You can rest assured that no sensitive data will be collected or tracked. %1$sLearn more%2$s.', 'just-tables' ), '<a target="_blank" href="' . esc_url( $this->privacy_policy ) . '">', '</a>' );
     561        $message_l2 = sprintf(
     562            /* translators: %1$s: Privacy Policy Link */
     563            esc_html__( 'Server information (Web server, PHP version, MySQL version), WordPress information, site name, site URL, number of plugins, number of users, your name, and email address. You can rest assured that no sensitive data will be collected or tracked. %1$sPrivacy Policy%2$s', 'just-tables' ), '<a target="_blank" href="' . esc_url( $this->privacy_policy ) . '">', '</a>' );
    482564
    483565        $button_text_1 = esc_html__( 'Count Me In', 'just-tables' );
    484566        $button_link_1 = add_query_arg( array( 'justtables_diagnostic_data_agreed' => 'yes' ) );
    485567
    486         $button_text_2 = esc_html__( 'No, Thanks', 'just-tables' );
     568        $button_text_2 = esc_html__( 'No thanks', 'just-tables' );
    487569        $button_link_2 = add_query_arg( array( 'justtables_diagnostic_data_agreed' => 'no' ) );
    488570        ?>
    489         <div class="justtables-diagnostic-data-style"><style>.justtables-diagnostic-data-notice,.woocommerce-embed-page .justtables-diagnostic-data-notice{padding-top:.75em;padding-bottom:.75em;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-buttons,.justtables-diagnostic-data-notice .justtables-diagnostic-data-list,.justtables-diagnostic-data-notice .justtables-diagnostic-data-message{padding:.25em 2px;margin:0;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-list{display:none;color:#646970;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-buttons{padding-top:.75em;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-buttons .button{margin-right:5px;box-shadow:none;}.justtables-diagnostic-data-loading{position:relative;}.justtables-diagnostic-data-loading::before{position:absolute;content:"";width:100%;height:100%;top:0;left:0;background-color:rgba(255,255,255,.5);z-index:999;}.justtables-diagnostic-data-disagree{border-width:0px !important;background-color: transparent!important; padding: 0!important;}h4.justtables-diagnostic-data-title {margin: 0 0 10px 0;font-size: 1.04em;font-weight: 600;}</style></div>
    490         <div class="justtables-diagnostic-data-notice notice notice-success">
    491             <h4 class="justtables-diagnostic-data-title"><?php echo sprintf(
    492                 /* translators: %1$s: Project Name */
    493                 esc_html__('🌟 Enhance Your %1$s Experience as a Valued Contributor!','just-tables'), esc_html( $this->project_name )); ?></h4>
    494             <p class="justtables-diagnostic-data-message"><?php echo wp_kses_post( $message_l1 ); ?></p>
     571        <div class="justtables-diagnostic-data-style"><style>.justtables-diagnostic-data-notice,.woocommerce-embed-page .justtables-diagnostic-data-notice{padding-top:.75em;padding-bottom:.75em;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-buttons,.justtables-diagnostic-data-notice .justtables-diagnostic-data-list,.justtables-diagnostic-data-notice .justtables-diagnostic-data-message{padding:.25em 2px;margin:0;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-list{display:none;color:#646970;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-buttons{padding-top:.75em;}.justtables-diagnostic-data-notice .justtables-diagnostic-data-buttons .button{margin-right:5px;box-shadow:none;}.justtables-diagnostic-data-loading{position:relative;}.justtables-diagnostic-data-loading::before{position:absolute;content:"";width:100%;height:100%;top:0;left:0;background-color:rgba(255,255,255,.5);z-index:999;}.justtables-diagnostic-data-disagree{border-width:0px !important;background-color: transparent!important; padding: 0!important;}.justtables-diagnostic-data-list-toogle{cursor:pointer;color:#2271b1;text-decoration:none;}</style></div>
     572        <script type="text/javascript">jQuery(function($){$(".justtables-diagnostic-data-list-toogle").on("click",function(e){e.preventDefault();$(this).closest(".justtables-diagnostic-data-notice").find(".justtables-diagnostic-data-list").slideToggle("fast")})});</script>
     573        <div class="justtables-diagnostic-data-notice notice notice-info">
     574            <p class="justtables-diagnostic-data-message"><?php echo wp_kses_post( sprintf( esc_html__( 'Want to help make %2$s%1$s%3$s even more awesome? Allow %1$s to collect diagnostic data and usage information. (%4$swhat we collect%5$s)', 'just-tables' ), esc_html( $this->project_name ), '<strong>', '</strong>', '<a href="#" class="justtables-diagnostic-data-list-toogle">', '</a>' ) ); ?></p>
    495575            <p class="justtables-diagnostic-data-list"><?php echo wp_kses_post( $message_l2 ); ?></p>
    496576            <p class="justtables-diagnostic-data-buttons">
  • just-tables/trunk/includes/Admin/class-deactivation.php

    r3206159 r3470073  
    11<?php
    2 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
    3 /**
    4  * Add Plugin Deactivation Feedback
    5  */
     2
     3// If this file is accessed directly, exit.
     4if ( ! defined( 'ABSPATH' ) ) {
     5    exit;
     6}
     7
    68class Just_Table_Plugin_Deactivation_Feedback {
    79
     
    1416    public $PROJECT_PRO_INSTALL;
    1517    public $PROJECT_PRO_VERSION;
    16     // public $DATA_CENTER = 'https://webhook.site/2bf26ba9-09fe-44f2-a007-8f433a4c95f5'; // For testing purpose only
    17     public $DATA_CENTER = 'https://connect.pabbly.com/workflow/sendwebhookdata/IjU3NjAwNTY1MDYzZTA0MzM1MjY1NTUzNyI_3D_pc';
    18 
    19     private static $_instance = null;
    20     /**
    21      * Class Instance
    22      */
    23     public static function instance(){
    24         if( is_null( self::$_instance ) ){
    25             self::$_instance = new self();
    26         }
    27         return self::$_instance;
    28     }
    29    
    30     public function __construct() {
     18    public $DATA_CENTER = 'https://exit-feedback.hasthemes.com/w/c351eb7b-c2e5-4136-bf8c-d6cb214ed130';
     19    public $WEBHOOK_SECRET = '8668b0a4f9df354ea68b04567c31f6c78be39a735b10f16fb978a788beaa3945';
     20
     21    public function init() {
    3122        $this->PROJECT_PRO_ACTIVE = $this->is_pro_plugin_active();
    3223        $this->PROJECT_PRO_INSTALL = $this->is_pro_plugin_installed();
    3324        $this->PROJECT_PRO_VERSION = $this->get_pro_version();
    34         add_action('admin_footer', [ $this, 'deactivation_feedback' ]);
    35         add_action('wp_ajax_just_Table_plugin_deactivation_feedback', [ $this, 'handle_feedback' ]);
    36     }
    37 
     25       
     26        add_action( 'admin_footer', [ $this, 'deactivation_feedback' ] );
     27        add_action( 'wp_ajax_justtables_deactivation_feedback', [ $this, 'handle_feedback' ] );
     28    }
     29   
     30    public function deactivation_feedback() {
     31        // Only show on plugins page
     32        $screen = get_current_screen();
     33        if ($screen->id !== 'plugins') {
     34            return;
     35        }
     36
     37        $this->deactivation_form_html();
     38    }
    3839   
    3940    /**
     
    4142     */
    4243    public function handle_feedback() {
    43             // Add nonce verification
    44         if ( !check_ajax_referer('hashbar_deactivation', 'nonce', false) ) {
     44        // Add nonce verification
     45        if ( !check_ajax_referer('justtables_deactivation_nonce', 'nonce', false) ) {
    4546            wp_send_json_error('Invalid nonce');
    4647            return;
     
    5152            return;
    5253        }
     54       
    5355        // Sanitize and prepare data
    5456        $reason = sanitize_text_field($_POST['reason']);
     
    6466        );
    6567
     68        $body = wp_json_encode( $data );
     69
    6670        $site_url = wp_parse_url( home_url(), PHP_URL_HOST );
    6771        $headers = [
    68             'user-agent' => $this->PROJECT_NAME . '/' . md5 ( $site_url ) . ';',
    69             'Content-Type'     => 'application/json',
    70         ];
     72            'user-agent'   => $this->PROJECT_NAME . '/' . md5( $site_url ) . ';',
     73            'Content-Type' => 'application/json',
     74        ];
     75
     76        $signature = $this->generate_signature( $body );
     77        if ( ! empty( $signature ) ) {
     78            $headers['X-Webhook-Signature'] = $signature;
     79        }
    7180
    7281        // Send data to Pabbly
     
    7988            'sslverify'   => false,
    8089            'headers'     => $headers,
    81             'body'        => wp_json_encode($data),
     90            'body'        => $body,
    8291            'cookies'     => []
    8392        ]);
     
    92101
    93102    public function get_data() {
    94         $hash = md5( current_time( 'U', true ) );
    95103
    96104        // Get plugin specific information
     
    105113
    106114        $site_title = get_bloginfo( 'name' );
    107         $site_description = get_bloginfo( 'description' );
    108115        $site_url = wp_parse_url( home_url(), PHP_URL_HOST );
    109116        $admin_email = get_option( 'admin_email' );
     
    131138        $ip_address = $this->get_ip_address();
    132139
    133         // Get Plugins
    134         $all_plugins = get_plugins();
    135         $active_plugins = get_option('active_plugins');
    136         $plugins_string = '';
    137         foreach($all_plugins as $plugin_path => $plugin) {
    138             $plugins_string .= sprintf(
    139                 "%s (v%s) - %s | ",
    140                 $plugin['Name'],
    141                 $plugin['Version'],
    142                 in_array($plugin_path, $active_plugins) ? 'Active' : 'Inactive'
    143             );
    144         }
    145         $plugins_string = rtrim($plugins_string, ' | ');
    146         // Get Themes
    147         $all_themes = wp_get_themes();
    148         $active_theme = wp_get_theme();
    149         $themes_string = '';
    150         foreach($all_themes as $theme_slug => $theme) {
    151             $themes_string .= sprintf(
    152                 "%s (v%s) - %s | ",
    153                 $theme->get('Name'),
    154                 $theme->get('Version'),
    155                 ($theme_slug === $active_theme->get_stylesheet()) ? 'Active' : 'Inactive'
    156             );
    157         }
    158         $themes_string = rtrim($themes_string, ' | ');
    159 
    160 
    161140        $data = [
    162             'hash'    => $hash,
    163             'project' => $project,
     141            'project'            => $project,
    164142            'site_title'         => $site_title,
    165             'site_description'   => $site_description,
    166143            'site_address'       => $site_url,
    167144            'site_url'           => $site_url,
     
    172149            'server_info'        => $this->get_server_info(),
    173150            'wordpress_info'     => $this->get_wordpress_info(),
    174             'users_count'        => $this->get_users_count(),
    175151            'plugins_count'      => $this->get_plugins_count(),
    176152            'ip_address'         => $ip_address,
    177153            'country_name'       => $this->get_country_from_ip( $ip_address ),
    178             'plugin_list'       => $plugins_string,
    179             'theme_list'        => $themes_string,
     154            'plugin_list'        => $this->get_active_plugins(),
     155            'install_time'       => get_option('just_tables_installed'),
    180156        ];
    181157
     
    192168        $php_version = function_exists ( 'phpversion' ) ? phpversion () : '';
    193169        $mysql_version = method_exists ( $wpdb, 'db_version' ) ? $wpdb->db_version () : '';
    194         $php_max_upload_size = size_format( wp_max_upload_size() );
    195         $php_default_timezone = date_default_timezone_get();
    196         $php_soap = class_exists ( 'SoapClient' ) ? 'yes' : 'no';
    197         $php_fsockopen = function_exists ( 'fsockopen' ) ? 'yes' : 'no';
    198         $php_curl = function_exists ( 'curl_init' ) ? 'yes' : 'no';
    199170
    200171        $server_info = array(
     
    202173            'php_version'          => $php_version,
    203174            'mysql_version'        => $mysql_version,
    204             'php_max_upload_size'  => $php_max_upload_size,
    205             'php_default_timezone' => $php_default_timezone,
    206             'php_soap'             => $php_soap,
    207             'php_fsockopen'        => $php_fsockopen,
    208             'php_curl'             => $php_curl,
    209175        );
    210176
     
    218184        $wordpress_info = [];
    219185
    220         $memory_limit = defined ( 'WP_MEMORY_LIMIT' ) ? WP_MEMORY_LIMIT : '';
    221186        $debug_mode = ( defined ( 'WP_DEBUG' ) && WP_DEBUG ) ? 'yes' : 'no';
    222187        $locale = get_locale();
    223188        $version = get_bloginfo( 'version' );
    224         $multisite = is_multisite () ? 'yes' : 'no';
    225189        $theme_slug = get_stylesheet();
    226190
    227191        $wordpress_info = [
    228             'memory_limit' => $memory_limit,
    229192            'debug_mode'   => $debug_mode,
    230193            'locale'       => $locale,
    231194            'version'      => $version,
    232             'multisite'    => $multisite,
    233195            'theme_slug'   => $theme_slug,
    234196        ];
     
    311273
    312274    /**
     275     * Get active plugins.
     276     */
     277    private function get_active_plugins() {
     278        $active_plugins = get_option('active_plugins');
     279        $all_plugins = get_plugins();
     280        $active_plugin_string = '';
     281        foreach($all_plugins as $plugin_path => $plugin) {
     282            if ( ! in_array($plugin_path, $active_plugins) ) {
     283                continue;
     284            }
     285            $active_plugin_string .= sprintf(
     286                "%s (v%s) - %s | ",
     287                $plugin['Name'],
     288                $plugin['Version'],
     289                'Active'
     290            );
     291        }
     292        $active_plugin_string = rtrim($active_plugin_string, ' | ');
     293        return $active_plugin_string;
     294    }
     295
     296    /**
    313297     * Get IP Address
    314298     */
     
    351335            return 'Unknown';
    352336        }
     337    }
     338
     339    /**
     340     * Generate HMAC-SHA256 signature for webhook payload.
     341     */
     342    private function generate_signature( $payload ) {
     343        if ( empty( $this->WEBHOOK_SECRET ) ) {
     344            return '';
     345        }
     346        return 'sha256=' . hash_hmac( 'sha256', $payload, $this->WEBHOOK_SECRET );
    353347    }
    354348
     
    381375    }
    382376
    383     public function deactivation_feedback() {
    384         // Only show on plugins page
    385         $screen = get_current_screen();
    386         if ($screen->id !== 'plugins') {
    387             return;
    388         }
    389         $this->deactivation_form_html();
    390         $this->deactivation_form_js();
    391         $this->deactivation_form_css();
    392     }
    393 
    394     public function deactivation_form_html() { ?>
    395         <div id="ht-deactivation-dialog" style="display: none;">
    396             <div class="ht-deactivation-dialog-content">
    397                 <button type="button" class="ht-close-dialog" aria-label="Close">&times;</button>
    398                 <h2 class="ht-deactivation-dialog-title"><?php esc_html_e('Quick Feedback', 'just-tables') ?></h2>
    399                 <p class="ht-deactivation-dialog-desc"><?php esc_html_e('If you have a moment, please let us know why you are deactivating:', 'just-tables'); echo esc_html($this->PROJECT_NAME); ?></p>
    400                 <form id="ht-deactivation-feedback-form">
    401                     <div class="ht-feedback-options">
    402                         <label>
    403                             <input type="radio" name="reason" data-id="found_better" value="<?php esc_attr_e('I found a better plugin', 'just-tables') ?>">
    404                             <?php esc_html_e('I found a better plugin', 'just-tables') ?>
    405                         </label>
    406                         <div id="ht-found_better-reason-text" class="ht-deactivation-reason-input" style="display: none;">
    407                             <textarea name="found_better_reason" placeholder="<?php esc_attr_e('Please share which plugin.', 'just-tables') ?>"></textarea>
    408                         </div>
    409                         <label>
    410                             <input type="radio" name="reason" data-id="stopped_working" value="<?php esc_attr_e('The plugin suddenly stopped working', 'just-tables') ?>">
    411                             <?php esc_html_e('The plugin suddenly stopped working', 'just-tables') ?>
    412                         </label>
    413                         <div id="ht-stopped_working-reason-text" class="ht-deactivation-reason-input" style="display: none;">
    414                             <textarea name="stopped_working_reason" placeholder="<?php esc_attr_e('Please share more details.', 'just-tables') ?>"></textarea>
    415                         </div>
    416                         <label>
    417                             <input type="radio" name="reason" data-id="found_bug" value="<?php esc_attr_e('I encountered an error or bug', 'just-tables') ?>">
    418                             <?php esc_html_e('I encountered an error or bug', 'just-tables') ?>
    419                         </label>
    420                         <div id="ht-found_bug-reason-text" class="ht-deactivation-reason-input" style="display: none;">
    421                             <textarea name="found_bug_reason" placeholder="<?php esc_attr_e('Please describe the error/bug you encountered. This will help us fix it for future users.', 'just-tables') ?>"></textarea>
    422                         </div>
    423                         <label>
    424                             <input type="radio" name="reason" data-id="not_working" value="<?php esc_attr_e("I could not get the plugin to work", 'just-tables') ?>">
    425                             <?php esc_html_e("I could not get the plugin to work", 'just-tables') ?>
    426                         </label>
    427                         <label>
    428                             <input type="radio" name="reason" data-id="" value="<?php esc_attr_e('I no longer need the plugin', 'just-tables') ?>">
    429                             <?php esc_html_e('I no longer need the plugin', 'just-tables') ?>
    430                         </label>
    431                         <label>
    432                             <input type="radio" name="reason" data-id="" value="<?php esc_attr_e("It's a temporary deactivation", 'just-tables') ?>">
    433                             <?php esc_html_e("It's a temporary deactivation", 'just-tables') ?>
    434                         </label>
    435                         <label>
    436                             <input type="radio" name="reason" data-id="other" value="<?php esc_attr_e("Other", 'just-tables') ?>">
    437                             <?php esc_html_e("Other", 'just-tables') ?>
    438                         </label>
    439                         <div id="ht-other-reason-text" class="ht-deactivation-reason-input" style="display: none;">
    440                             <textarea name="other_reason" placeholder="<?php esc_attr_e("Please share the reason.", 'just-tables') ?>"></textarea>
    441                         </div>
    442                     </div>
    443                     <div class="ht-deactivation-dialog-buttons">
    444                         <button type="submit" class="button button-primary"><?php esc_html_e("Submit & Deactivate", 'just-tables') ?></button>
    445                         <a href="#" class="ht-skip-feedback"><?php esc_html_e("Skip & Deactivate", 'just-tables') ?></a>
    446                     </div>
    447                 </form>
    448             </div>
    449         </div>
    450     <?php }
    451     public function deactivation_form_js() {
    452         $ajaxurl = admin_url('admin-ajax.php');
    453         $nonce = wp_create_nonce('hashbar_deactivation');
    454         ?>
    455         <script>
    456             jQuery(document).ready(function($) {
    457                 let pluginToDeactivate = '';
    458                
    459                 function closeDialog() {
    460                     $('#ht-deactivation-dialog').hide();
    461                     pluginToDeactivate = '';
    462                 }
    463                
    464                 $('[data-slug="<?php echo esc_attr($this->PROJECT_SLUG); ?>"] .deactivate a').on('click', function(e) {
    465                     e.preventDefault();
    466                     pluginToDeactivate = $(this).attr('href');
    467                     $('#ht-deactivation-dialog').show();
    468                 });
    469 
    470                 $('.ht-close-dialog').on('click', closeDialog);
    471 
    472                 $('#ht-deactivation-dialog').on('click', function(e) {
    473                     if (e.target === this) {
    474                         closeDialog();
    475                     }
    476                 });
    477                
    478                 $('.ht-deactivation-dialog-content').on('click', function(e) {
    479                     e.stopPropagation();
    480                 });
    481 
    482                 $('input[name="reason"]').on('change', function() {
    483                     $('.ht-deactivation-reason-input').removeClass('active').hide();
    484                    
    485                     const id = $(this).data('id');
    486                     if (['other', 'found_better', 'stopped_working', 'found_bug'].includes(id)) {
    487                         $(`#ht-${id}-reason-text`).addClass('active').show();
    488                     }
    489                 });
    490 
    491                 $('#ht-deactivation-feedback-form').on('submit', function(e) {
    492                     e.preventDefault();
    493                    
    494                     const $submitButton = $(this).find('button[type="submit"]');
    495                     const originalText = $submitButton.text();
    496                    
    497                     $submitButton.text('Submitting...').prop('disabled', true);
    498 
    499                     const reason = $('input[name="reason"]:checked').val();
    500                     const message = $('.ht-deactivation-reason-input.active textarea').val() || '';
    501                    
    502                     const data = {
    503                         action: 'just_Table_plugin_deactivation_feedback',
    504                         reason: reason,
    505                         message: message,
    506                         nonce: '<?php echo esc_js($nonce); ?>'
    507                     };
    508                     $.post('<?php echo esc_url_raw($ajaxurl); ?>', data)
    509                         .done(function(response) {
    510                             if (response.success) {
    511                                 window.location.href = pluginToDeactivate;
    512                             } else {
    513                                 console.error('Feedback submission failed:', response.data);
    514                                 $submitButton.text(originalText).prop('disabled', false);
    515                             }
    516                         })
    517                         .fail(function(xhr) {
    518                             console.error('Feedback submission failed:', xhr.responseText);
    519                             $submitButton.text(originalText).prop('disabled', false);
    520                         });
    521                 });
    522 
    523                 $('.ht-skip-feedback').on('click', function(e) {
    524                     e.preventDefault();
    525                     window.location.href = pluginToDeactivate;
    526                 });
    527             });
    528         </script>
    529         <?php
    530     }
    531     public function deactivation_form_css() { ?>
    532         <style>
    533             #ht-deactivation-dialog {
    534                 position: fixed;
    535                 top: 0;
    536                 left: 0;
    537                 right: 0;
    538                 bottom: 0;
    539                 background: rgba(0, 0, 0, 0.5);
    540                 z-index: 9999;
    541                 display: flex;
    542                 align-items: center;
    543                 justify-content: center;
    544             }
    545 
    546             .ht-deactivation-dialog-content {
    547                 background: #fff;
    548                 padding: 30px;
    549                 max-width: 500px;
    550                 width: 100%;
    551                 border-radius: 4px;
    552                 box-shadow: 0 2px 30px rgba(0, 0, 0, 0.1);
    553                 position: relative;
    554             }
    555             .ht-deactivation-dialog-title {
    556                 margin-top: 0;
    557             }
    558 
    559             .ht-close-dialog {
    560                 position: absolute;
    561                 top: 10px;
    562                 right: 10px;
    563                 width: 24px;
    564                 height: 24px;
    565                 border-radius: 50%;
    566                 background: #f0f0f0;
    567                 border: none;
    568                 cursor: pointer;
    569                 display: flex;
    570                 justify-content: center;
    571                 font-size: 18px;
    572                 line-height: 18px;
    573                 color: #333;
    574                 transition: all 0.2s ease;
    575                 font-weight: 700;
    576             }
    577 
    578             .ht-close-dialog:hover {
    579                 background: #e0e0e0;
    580                 color: #333;
    581             }
    582 
    583             .ht-feedback-options {
    584                 margin: 20px 0;
    585             }
    586 
    587             .ht-feedback-options label {
    588                 display: block;
    589                 margin: 10px 0;
    590             }
    591 
    592 
    593             .ht-deactivation-reason-input {
    594                 margin-bottom: 15px;
    595             }
    596             .ht-deactivation-reason-input textarea {
    597                 width: 100%;
    598                 min-height: 60px;
    599                 padding: 6px 8px;
    600                 display: block;
    601             }
    602 
    603             .ht-deactivation-dialog-buttons {
    604                 margin-top: 20px;
    605                 display: flex;
    606                 align-items: center;
    607                 justify-content: flex-end;
    608             }
    609 
    610             .ht-skip-feedback {
    611                 margin-left: 10px;
    612                 color: #666;
    613                 text-decoration: none;
    614             }
    615         </style>
    616     <?php }
     377    /**
     378     * Deactivation form html.
     379     */
     380    public function deactivation_form_html() {
     381        require_once JUST_TABLES_PATH.'/includes/Admin/deactive-feedback.php';
     382    }
     383
    617384}
    618385
    619 // Initialize the class
    620 Just_Table_Plugin_Deactivation_Feedback::instance();
     386$deactivation_feedback = new Just_Table_Plugin_Deactivation_Feedback();
     387$deactivation_feedback->init();
  • just-tables/trunk/just-tables.php

    r3419781 r3470073  
    44 * Plugin URI: https://hasthemes.com/wp/justtables/
    55 * Description: Display WooCommerce products as table.
    6  * Version: 1.8.0
     6 * Version: 1.8.1
    77 * Author: HasThemes
    88 * Author URI: https://hasthemes.com
     
    3737         * @var string $version
    3838         */
    39         public $version = '1.8.0';
     39        public $version = '1.8.1';
    4040
    4141        /**
  • just-tables/trunk/readme.txt

    r3419781 r3470073  
    44Requires at least: 5.0
    55Tested up to: 6.9
    6 Stable tag: 1.8.0
     6Stable tag: 1.8.1
    77License: GPLv2 or later
    88License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    112112== Changelog ==
    113113
     114= Version: 1.8.1 - Date: 26 February, 2026 =
     115* Improved: Admin notice display.
     116
    114117= Version: 1.8.0 - Date: 15 December, 2025 =
    115118* Added: Table duplicate feature - easily duplicate tables from the admin list.
Note: See TracChangeset for help on using the changeset viewer.