Plugin Directory

Changeset 3672709


Ignore:
Timestamp:
08/30/2026 02:49:17 PM (2 months ago)
Author:
shahadul878
Message:

Update trunk to version 1.1.7

Location:
easy-php-settings/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • easy-php-settings/trunk/class-easy-php-settings.php

    r3580052 r3672709  
    44 * Plugin URI:  https://github.com/easy-php-settings
    55 * Description: An easy way to manage common PHP INI settings from the WordPress admin panel.
    6  * Version:     1.1.6
     6 * Version:     1.1.7
    77 * Author:      H M Shahadul Islam
    88 * Author URI:  https://github.com/shahadul878
    … …  
    3838
    3939register_activation_hook( __FILE__, function () {
    40         if ( function_exists( 'tracker_integration_report_install' ) ) {
    41                 tracker_integration_report_install( __FILE__ );
     40        if ( function_exists( 'tracker_integration_on_activate' ) ) {
     41                tracker_integration_on_activate( __FILE__ );
    4242        }
    4343        // Best-effort: migrate any legacy DB-stored wp-config backups to the
    … …  
    6262
    6363register_deactivation_hook( __FILE__, function () {
    64         if ( function_exists( 'tracker_integration_report_deactivate' ) ) {
    65                 tracker_integration_report_deactivate( __FILE__ );
    66                 tracker_integration_unschedule_cron( __FILE__ );
     64        if ( function_exists( 'tracker_integration_on_deactivate' ) ) {
     65                tracker_integration_on_deactivate( __FILE__ );
    6766        }
    6867} );
    … …  
    117116         * @var string
    118117         */
    119         private $version = '1.1.6';
     118        private $version = '1.1.7';
    120119
    121120        /**
  • easy-php-settings/trunk/includes/plugin-tracker-integration.php

    r3580052 r3672709  
    33 * Plugin Tracker Integration – drop-in for existing WordPress plugins.
    44 *
    5  * Reports basic site and plugin usage to the Plugin Tracker API on
    6  * activation, weekly cron, and periodic admin sync.
     5 * Reports basic site and plugin usage to the Plugin Tracker API when the
     6 * administrator has explicitly opted in. No data is sent by default.
    77 *
    88 * @package PluginTrackerIntegration
    9  * @version 1.1.6
     9 * @version 1.1.7
    1010 * @author H M Shahadul Islam
    1111 * @license GPL-2.0+
    … …  
    2525
    2626const PLUGIN_TRACKER_PLUGIN_FILE_OPT = 'plugin_tracker_plugin_file';
     27const PLUGIN_TRACKER_CONSENT_OPT     = 'plugin_tracker_consent';
     28const PLUGIN_TRACKER_CONSENT_TIME_OPT = 'plugin_tracker_consent_time';
    2729const PLUGIN_TRACKER_KNOWN_OFFERS_OPT  = 'plugin_tracker_known_offer_ids';
    2830const PLUGIN_TRACKER_OFFER_NOTICES_OPT = 'plugin_tracker_offer_notices';
    … …  
    143145
    144146/**
    145  * Report install to Plugin Tracker API. Call from activation hook.
     147 * Whether the site administrator has opted in to third-party data sharing.
     148 *
     149 * @return bool
     150 */
     151function tracker_integration_has_consent() {
     152        return '1' === get_option( PLUGIN_TRACKER_CONSENT_OPT, '0' );
     153}
     154
     155/**
     156 * Register plugin on activation without sending any external data.
    146157 *
    147158 * @param string $plugin_file Path to the main plugin file.
    148159 */
    149 function tracker_integration_report_install( $plugin_file ) {
     160function tracker_integration_on_activate( $plugin_file ) {
    150161        $GLOBALS['plugin_tracker_integration_plugin_file'] = $plugin_file;
    151162        update_option( PLUGIN_TRACKER_PLUGIN_FILE_OPT, $plugin_file, false );
     163}
     164
     165/**
     166 * Opt in to data sharing: persist consent, send install report, schedule cron.
     167 *
     168 * @param string $plugin_file Path to the main plugin file.
     169 */
     170function tracker_integration_grant_consent( $plugin_file ) {
     171        update_option( PLUGIN_TRACKER_CONSENT_OPT, '1', false );
     172        update_option( PLUGIN_TRACKER_CONSENT_TIME_OPT, time(), false );
    152173
    153174        tracker_integration_delete_offers_cache();
    … …  
    157178
    158179/**
     180 * Revoke consent and stop all scheduled tracking.
     181 *
     182 * @param string $plugin_file     Path to the main plugin file.
     183 * @param bool   $send_deactivate Send a best-effort deactivate ping when consent was active.
     184 */
     185function tracker_integration_revoke_consent( $plugin_file, $send_deactivate = true ) {
     186        $had_consent = tracker_integration_has_consent();
     187
     188        if ( $send_deactivate && $had_consent && $plugin_file ) {
     189                tracker_integration_post( 'deactivate', tracker_integration_build_payload( $plugin_file ), false, false );
     190        }
     191
     192        update_option( PLUGIN_TRACKER_CONSENT_OPT, '0', false );
     193        delete_option( PLUGIN_TRACKER_CONSENT_TIME_OPT );
     194        tracker_integration_unschedule_cron( $plugin_file );
     195        tracker_integration_delete_offers_cache();
     196        delete_option( PLUGIN_TRACKER_KNOWN_OFFERS_OPT );
     197        delete_option( PLUGIN_TRACKER_OFFER_NOTICES_OPT );
     198}
     199
     200/**
     201 * Handle plugin deactivation: notify tracker only if opted in, always clear cron.
     202 *
     203 * @param string $plugin_file Path to the main plugin file.
     204 */
     205function tracker_integration_on_deactivate( $plugin_file ) {
     206        if ( tracker_integration_has_consent() ) {
     207                tracker_integration_report_deactivate( $plugin_file );
     208        }
     209        tracker_integration_unschedule_cron( $plugin_file );
     210}
     211
     212/**
     213 * URL to the About tab consent panel.
     214 *
     215 * @return string
     216 */
     217function tracker_integration_get_consent_settings_url() {
     218        return add_query_arg(
     219                array(
     220                        'page' => 'easy-php-settings',
     221                        'tab'  => 'about',
     222                ),
     223                admin_url( 'tools.php' )
     224        );
     225}
     226
     227/**
     228 * Shared disclosure copy for opt-in UI.
     229 *
     230 * @return array<string, string>
     231 */
     232function tracker_integration_get_disclosure_fields() {
     233        return array(
     234                __( 'Site URL', 'easy-php-settings' ),
     235                __( 'WordPress, PHP, and plugin versions', 'easy-php-settings' ),
     236                __( 'Server software', 'easy-php-settings' ),
     237                __( 'Administrator email address and display name', 'easy-php-settings' ),
     238                __( 'Installed plugins and themes (name, version, active status)', 'easy-php-settings' ),
     239        );
     240}
     241
     242/**
     243 * @deprecated 1.1.7 Use tracker_integration_on_activate() instead.
     244 * @param string $plugin_file Path to the main plugin file.
     245 */
     246function tracker_integration_report_install( $plugin_file ) {
     247        tracker_integration_on_activate( $plugin_file );
     248}
     249
     250/**
    159251 * POST a payload to the tracker.
    160252 *
    161  * @param string $endpoint Path under PLUGIN_TRACKER_API_URL (e.g. 'install').
    162  * @param array  $payload  Body.
    163  * @param bool   $blocking Whether to wait for the HTTP response.
    164  */
    165 function tracker_integration_post( $endpoint, $payload, $blocking = false ) {
     253 * @param string $endpoint         Path under PLUGIN_TRACKER_API_URL (e.g. 'install').
     254 * @param array  $payload          Body.
     255 * @param bool   $blocking         Whether to wait for the HTTP response.
     256 * @param bool   $require_consent  When true, abort if the site has not opted in.
     257 */
     258function tracker_integration_post( $endpoint, $payload, $blocking = false, $require_consent = true ) {
     259        if ( $require_consent && ! tracker_integration_has_consent() ) {
     260                return;
     261        }
    166262        if ( '' === PLUGIN_TRACKER_API_KEY ) {
    167263                return;
    … …  
    239335 */
    240336function tracker_integration_report_deactivate( $plugin_file ) {
    241         tracker_integration_post( 'deactivate', tracker_integration_build_payload( $plugin_file ), false );
     337        if ( ! tracker_integration_has_consent() ) {
     338                return;
     339        }
     340        tracker_integration_post( 'deactivate', tracker_integration_build_payload( $plugin_file ), false, false );
    242341}
    243342
    … …  
    266365
    267366        delete_option( PLUGIN_TRACKER_PLUGIN_FILE_OPT );
    268         delete_option( 'plugin_tracker_consent' );
    269         delete_option( 'plugin_tracker_consent_time' );
     367        delete_option( PLUGIN_TRACKER_CONSENT_OPT );
     368        delete_option( PLUGIN_TRACKER_CONSENT_TIME_OPT );
    270369        delete_option( PLUGIN_TRACKER_KNOWN_OFFERS_OPT );
    271370        delete_option( PLUGIN_TRACKER_OFFER_NOTICES_OPT );
    272371
    273372        $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE '_transient_plugin_tracker_%' OR option_name LIKE '_transient_timeout_plugin_tracker_%'" );
    274         $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => 'plugin_tracker_notice_dismissed' ) );
     373        $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => 'plugin_tracker_optin_dismissed' ) );
    275374}
    276375
    … …  
    279378        'upgrader_process_complete',
    280379        function ( $upgrader, $options ) {
     380                if ( ! tracker_integration_has_consent() ) {
     381                        return;
     382                }
    281383                if ( ! isset( $options['type'] ) || 'plugin' !== $options['type'] ) {
    282384                        return;
    … …  
    314416                        $hook,
    315417                        function () use ( $plugin_file ) {
     418                                if ( ! tracker_integration_has_consent() ) {
     419                                        return;
     420                                }
    316421                                tracker_integration_ping( $plugin_file );
    317422                        }
    … …  
    325430        'admin_init',
    326431        function () {
     432                if ( ! tracker_integration_has_consent() ) {
     433                        return;
     434                }
    327435                if ( ! current_user_can( 'manage_options' ) ) {
    328436                        return;
    … …  
    389497 */
    390498function tracker_integration_get_offers( $force_refresh = false ) {
     499        if ( ! tracker_integration_has_consent() ) {
     500                return array();
     501        }
    391502        if ( '' === PLUGIN_TRACKER_API_KEY ) {
    392503                return array();
    … …  
    608719                        plugins_url( 'css/admin-styles.css', dirname( __DIR__ ) . '/class-easy-php-settings.php' ),
    609720                        array(),
    610                         defined( 'PLUGIN_TRACKER_PLUGIN_VERSION' ) ? PLUGIN_TRACKER_PLUGIN_VERSION : '1.1.6'
     721                        defined( 'PLUGIN_TRACKER_PLUGIN_VERSION' ) ? PLUGIN_TRACKER_PLUGIN_VERSION : '1.1.7'
    611722                );
    612723        }
    … …  
    634745 */
    635746function tracker_integration_render_dashboard_widget() {
     747        if ( ! tracker_integration_has_consent() ) {
     748                echo '<p style="margin:0;">' . esc_html__( 'Optional: share anonymous site usage data to receive service offers and support updates from CodeEyes.', 'easy-php-settings' ) . '</p>';
     749                echo '<p style="margin:8px 0 0;"><a href="' . esc_url( tracker_integration_get_consent_settings_url() ) . '">' . esc_html__( 'Manage data sharing preferences', 'easy-php-settings' ) . '</a></p>';
     750                return;
     751        }
     752
    636753        $offers = tracker_integration_get_offers();
    637754        if ( empty( $offers ) ) {
    … …  
    724841 */
    725842function tracker_integration_get_active_offer_notice() {
     843        if ( ! tracker_integration_has_consent() ) {
     844                return null;
     845        }
    726846        if ( ! current_user_can( 'manage_options' ) ) {
    727847                return null;
    … …  
    813933
    814934        $plugin_file = dirname( __DIR__ ) . '/class-easy-php-settings.php';
    815         $version     = defined( 'PLUGIN_TRACKER_PLUGIN_VERSION' ) ? PLUGIN_TRACKER_PLUGIN_VERSION : '1.1.6';
     935        $version     = defined( 'PLUGIN_TRACKER_PLUGIN_VERSION' ) ? PLUGIN_TRACKER_PLUGIN_VERSION : '1.1.7';
    816936        $offer       = $active['offer'];
    817937        $offer_id    = isset( $offer['id'] ) ? (string) $offer['id'] : '';
    … …  
    9921112
    9931113/* ──────────────────────────────────────────────
    994    Informational privacy notice (dismissible)
     1114   Opt-in consent notice and About tab controls
    9951115   ────────────────────────────────────────────── */
    9961116
    997 add_action(
    998         'admin_notices',
    999         function () {
    1000                 if ( ! current_user_can( 'manage_options' ) ) {
     1117/**
     1118 * Whether to show the first-run opt-in admin notice.
     1119 *
     1120 * @return bool
     1121 */
     1122function tracker_integration_should_show_optin_notice() {
     1123        if ( ! is_admin() || wp_doing_ajax() ) {
     1124                return false;
     1125        }
     1126        if ( ! current_user_can( 'manage_options' ) ) {
     1127                return false;
     1128        }
     1129        if ( tracker_integration_has_consent() ) {
     1130                return false;
     1131        }
     1132        if ( ! get_option( PLUGIN_TRACKER_PLUGIN_FILE_OPT ) ) {
     1133                return false;
     1134        }
     1135        if ( get_user_meta( get_current_user_id(), 'plugin_tracker_optin_dismissed', true ) ) {
     1136                return false;
     1137        }
     1138        return true;
     1139}
     1140
     1141/**
     1142 * Handle grant/revoke consent form submissions.
     1143 */
     1144function tracker_integration_handle_consent_actions() {
     1145        if ( ! current_user_can( 'manage_options' ) ) {
     1146                return;
     1147        }
     1148
     1149        $plugin_file = get_option( PLUGIN_TRACKER_PLUGIN_FILE_OPT );
     1150        if ( ! $plugin_file ) {
     1151                return;
     1152        }
     1153
     1154        if ( isset( $_POST['plugin_tracker_consent_action'], $_POST['plugin_tracker_consent_nonce'] ) ) {
     1155                if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['plugin_tracker_consent_nonce'] ) ), 'plugin_tracker_consent' ) ) {
    10011156                        return;
    10021157                }
    1003                 if ( get_user_meta( get_current_user_id(), 'plugin_tracker_notice_dismissed', true ) ) {
     1158
     1159                $action = sanitize_key( wp_unslash( $_POST['plugin_tracker_consent_action'] ) );
     1160                if ( 'grant' === $action ) {
     1161                        tracker_integration_grant_consent( $plugin_file );
     1162                        delete_user_meta( get_current_user_id(), 'plugin_tracker_optin_dismissed' );
     1163                        add_settings_error( 'plugin_tracker_consent', 'granted', __( 'Data sharing enabled. You can revoke this at any time from the About tab.', 'easy-php-settings' ), 'updated' );
     1164                } elseif ( 'revoke' === $action ) {
     1165                        tracker_integration_revoke_consent( $plugin_file, true );
     1166                        add_settings_error( 'plugin_tracker_consent', 'revoked', __( 'Data sharing disabled. No further information will be sent to the third-party service.', 'easy-php-settings' ), 'updated' );
     1167                }
     1168
     1169                set_transient( 'settings_errors', get_settings_errors(), 30 );
     1170                wp_safe_redirect( tracker_integration_get_consent_settings_url() );
     1171                exit;
     1172        }
     1173
     1174        if ( isset( $_GET['plugin_tracker_decline'], $_GET['_wpnonce'] ) ) {
     1175                if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'plugin_tracker_decline' ) ) {
    10041176                        return;
    10051177                }
    1006                 if ( ! get_option( PLUGIN_TRACKER_PLUGIN_FILE_OPT ) ) {
    1007                         return;
    1008                 }
    1009 
    1010                 $nonce       = wp_create_nonce( 'plugin_tracker_dismiss_notice' );
    1011                 $dismiss_url = add_query_arg(
    1012                         array(
    1013                                 'plugin_tracker_dismiss' => '1',
    1014                                 '_wpnonce'               => $nonce,
    1015                         ),
    1016                         admin_url()
    1017                 );
    1018                 ?>
    1019                 <div class="notice notice-info plugin-tracker-notice is-dismissible">
    1020                         <p style="margin:0.5em 0;">
    1021                                 <strong><?php esc_html_e( 'Easy PHP Settings — usage data', 'easy-php-settings' ); ?></strong>
    1022                                 <?php esc_html_e( 'This plugin sends your site URL, WordPress version, PHP version, plugin version, admin email, and installed plugin/theme lists to improve plugin services. See the About tab for details.', 'easy-php-settings' ); ?>
    1023                                 <a href="<?php echo esc_url( $dismiss_url ); ?>" class="notice-dismiss" style="text-decoration:none;"><span class="screen-reader-text"><?php esc_attr_e( 'Dismiss', 'easy-php-settings' ); ?></span></a>
    1024                         </p>
    1025                 </div>
    1026                 <?php
    1027         }
    1028 );
    1029 
    1030 add_action(
    1031         'admin_init',
    1032         function () {
    1033                 if ( ! isset( $_GET['plugin_tracker_dismiss'], $_GET['_wpnonce'] ) ) {
    1034                         return;
    1035                 }
    1036                 if ( ! current_user_can( 'manage_options' ) ) {
    1037                         return;
    1038                 }
    1039                 if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'plugin_tracker_dismiss_notice' ) ) {
    1040                         return;
    1041                 }
    1042                 update_user_meta( get_current_user_id(), 'plugin_tracker_notice_dismissed', 1 );
    1043                 wp_safe_redirect( remove_query_arg( array( 'plugin_tracker_dismiss', '_wpnonce' ) ) );
     1178                update_user_meta( get_current_user_id(), 'plugin_tracker_optin_dismissed', 1 );
     1179                wp_safe_redirect( remove_query_arg( array( 'plugin_tracker_decline', '_wpnonce' ) ) );
    10441180                exit;
    10451181        }
    1046 );
    1047 
    1048 /**
    1049  * Render informational privacy section for the About tab.
    1050  */
    1051 function tracker_integration_render_consent_panel() {
     1182}
     1183add_action( 'admin_init', 'tracker_integration_handle_consent_actions' );
     1184
     1185/**
     1186 * Render the optional opt-in admin notice.
     1187 */
     1188function tracker_integration_render_optin_notice() {
     1189        if ( ! tracker_integration_should_show_optin_notice() ) {
     1190                return;
     1191        }
     1192
     1193        $about_url   = tracker_integration_get_consent_settings_url();
     1194        $decline_url = wp_nonce_url(
     1195                add_query_arg( 'plugin_tracker_decline', '1', admin_url() ),
     1196                'plugin_tracker_decline'
     1197        );
     1198        $fields      = tracker_integration_get_disclosure_fields();
    10521199        ?>
    1053         <div class="card" style="max-width:640px;padding:1em 1.5em;">
    1054                 <h2 style="margin-top:0;"><?php esc_html_e( 'Privacy & data sharing', 'easy-php-settings' ); ?></h2>
    1055                 <p>
    1056                         <?php esc_html_e( 'Easy PHP Settings sends the following data to the developer to improve plugin services and support:', 'easy-php-settings' ); ?>
     1200        <div class="notice notice-info plugin-tracker-optin-notice">
     1201                <p style="margin:0.5em 0 0.25em;">
     1202                        <strong><?php esc_html_e( 'Easy PHP Settings — optional data sharing', 'easy-php-settings' ); ?></strong>
    10571203                </p>
    1058                 <ul style="list-style:disc;margin-left:1.5em;">
    1059                         <li><?php esc_html_e( 'Site URL', 'easy-php-settings' ); ?></li>
    1060                         <li><?php esc_html_e( 'WordPress, PHP, and plugin versions', 'easy-php-settings' ); ?></li>
    1061                         <li><?php esc_html_e( 'Server software', 'easy-php-settings' ); ?></li>
    1062                         <li><?php esc_html_e( 'Admin email and display name', 'easy-php-settings' ); ?></li>
    1063                         <li><?php esc_html_e( 'List of installed plugins and themes', 'easy-php-settings' ); ?></li>
     1204                <p style="margin:0.25em 0;">
     1205                        <?php
     1206                        printf(
     1207                                /* translators: %s: third-party service URL */
     1208                                esc_html__( 'You may optionally share site information with Plugin Tracker (CodeEyes) at %s to receive plugin support updates and service offers. Data sharing is disabled by default.', 'easy-php-settings' ),
     1209                                'https://plugin.codereyes.com/'
     1210                        );
     1211                        ?>
     1212                </p>
     1213                <p style="margin:0.25em 0;"><strong><?php esc_html_e( 'If you opt in, the following data may be sent:', 'easy-php-settings' ); ?></strong></p>
     1214                <ul style="list-style:disc;margin:0.25em 0 0.5em 1.5em;">
     1215                        <?php foreach ( $fields as $field ) : ?>
     1216                                <li><?php echo esc_html( $field ); ?></li>
     1217                        <?php endforeach; ?>
    10641218                </ul>
    1065                 <p>
    1066                         <?php esc_html_e( 'Data is sent on plugin activation and periodically while the plugin is active. Weekly pings and hourly admin sync keep the information up to date.', 'easy-php-settings' ); ?>
     1219                <p style="margin:0.25em 0 0.75em;">
     1220                        <?php esc_html_e( 'When sent: once when you opt in, then at most once per week via a scheduled task, at most once per hour during admin use, after plugin updates, and once on deactivation if you had opted in. Purpose: improve plugin support and related services. See the plugin readme Privacy Policy section for details.', 'easy-php-settings' ); ?>
     1221                </p>
     1222                <p style="margin:0 0 0.75em;">
     1223                        <form method="post" action="" style="display:inline;margin-right:6px;">
     1224                                <?php wp_nonce_field( 'plugin_tracker_consent', 'plugin_tracker_consent_nonce' ); ?>
     1225                                <input type="hidden" name="plugin_tracker_consent_action" value="grant" />
     1226                                <button type="submit" class="button button-primary"><?php esc_html_e( 'Allow data sharing', 'easy-php-settings' ); ?></button>
     1227                        </form>
     1228                        <a class="button" href="<?php echo esc_url( $about_url ); ?>#plugin-tracker-consent-panel"><?php esc_html_e( 'Learn more', 'easy-php-settings' ); ?></a>
     1229                        <a class="button" href="<?php echo esc_url( $decline_url ); ?>"><?php esc_html_e( 'No thanks', 'easy-php-settings' ); ?></a>
    10671230                </p>
    10681231        </div>
    10691232        <?php
    10701233}
     1234add_action( 'admin_notices', 'tracker_integration_render_optin_notice' );
     1235add_action( 'network_admin_notices', 'tracker_integration_render_optin_notice' );
     1236
     1237/**
     1238 * Register suggested privacy policy text for Site Health / Privacy tools.
     1239 */
     1240function tracker_integration_register_privacy_policy_content() {
     1241        if ( ! function_exists( 'wp_add_privacy_policy_content' ) ) {
     1242                return;
     1243        }
     1244
     1245        $content = '<p>' . esc_html__( 'Easy PHP Settings can optionally send site information to Plugin Tracker (CodeEyes) at https://plugin.codereyes.com/ when an administrator explicitly opts in from the About tab. No data is sent by default.', 'easy-php-settings' ) . '</p>';
     1246        $content .= '<p><strong>' . esc_html__( 'Data that may be sent after opt-in:', 'easy-php-settings' ) . '</strong></p><ul>';
     1247        foreach ( tracker_integration_get_disclosure_fields() as $field ) {
     1248                $content .= '<li>' . esc_html( $field ) . '</li>';
     1249        }
     1250        $content .= '</ul>';
     1251        $content .= '<p>' . esc_html__( 'Frequency: on opt-in, weekly cron, hourly admin sync at most, after plugin updates, and on deactivation if opted in. You can revoke consent at any time from Tools → Easy PHP Settings → About.', 'easy-php-settings' ) . '</p>';
     1252
     1253        wp_add_privacy_policy_content( 'Easy PHP Settings', $content );
     1254}
     1255add_action( 'admin_init', 'tracker_integration_register_privacy_policy_content' );
     1256
     1257/**
     1258 * Render opt-in controls for the About tab.
     1259 */
     1260function tracker_integration_render_consent_panel() {
     1261        if ( $settings_errors = get_transient( 'settings_errors' ) ) {
     1262                global $wp_settings_errors;
     1263                $wp_settings_errors = array_merge( (array) $wp_settings_errors, $settings_errors );
     1264                delete_transient( 'settings_errors' );
     1265        }
     1266
     1267        $plugin_file = get_option( PLUGIN_TRACKER_PLUGIN_FILE_OPT );
     1268        $has_consent = tracker_integration_has_consent();
     1269        $consented_at = (int) get_option( PLUGIN_TRACKER_CONSENT_TIME_OPT, 0 );
     1270        $fields       = tracker_integration_get_disclosure_fields();
     1271        ?>
     1272        <div id="plugin-tracker-consent-panel" class="easy-php-about-card">
     1273                <h3 class="easy-php-about-card-title"><span class="dashicons dashicons-privacy"></span> <?php esc_html_e( 'Privacy & Data Sharing', 'easy-php-settings' ); ?></h3>
     1274
     1275                <p>
     1276                        <?php esc_html_e( 'Data sharing with third-party services is optional and disabled by default. Easy PHP Settings works fully without enabling this feature.', 'easy-php-settings' ); ?>
     1277                </p>
     1278
     1279                <p>
     1280                        <strong><?php esc_html_e( 'Third-party service:', 'easy-php-settings' ); ?></strong>
     1281                        <a href="https://plugin.codereyes.com/" target="_blank" rel="noopener">Plugin Tracker (CodeEyes) — https://plugin.codereyes.com/</a>
     1282                </p>
     1283
     1284                <p><strong><?php esc_html_e( 'Data sent only after you opt in:', 'easy-php-settings' ); ?></strong></p>
     1285                <ul class="easy-php-about-list">
     1286                        <?php foreach ( $fields as $field ) : ?>
     1287                                <li><?php echo esc_html( $field ); ?></li>
     1288                        <?php endforeach; ?>
     1289                </ul>
     1290
     1291                <p>
     1292                        <?php esc_html_e( 'Purpose: improve plugin support and related services/offers. Frequency: on opt-in, weekly scheduled sync, hourly admin sync at most, after plugin updates, and on deactivation if you had opted in.', 'easy-php-settings' ); ?>
     1293                </p>
     1294
     1295                <p>
     1296                        <strong><?php esc_html_e( 'Current status:', 'easy-php-settings' ); ?></strong>
     1297                        <?php if ( $has_consent ) : ?>
     1298                                <span class="easy-php-badge easy-php-badge--success"><?php esc_html_e( 'Opted in', 'easy-php-settings' ); ?></span>
     1299                                <?php if ( $consented_at ) : ?>
     1300                                        <span class="description"><?php echo esc_html( sprintf( __( '(since %s)', 'easy-php-settings' ), wp_date( get_option( 'date_format' ), $consented_at ) ) ); ?></span>
     1301                                <?php endif; ?>
     1302                        <?php else : ?>
     1303                                <span class="easy-php-badge"><?php esc_html_e( 'Opted out (default)', 'easy-php-settings' ); ?></span>
     1304                        <?php endif; ?>
     1305                </p>
     1306
     1307                <?php settings_errors( 'plugin_tracker_consent' ); ?>
     1308
     1309                <?php if ( $plugin_file ) : ?>
     1310                        <form method="post" action="" class="easy-php-tracker-consent-form">
     1311                                <?php wp_nonce_field( 'plugin_tracker_consent', 'plugin_tracker_consent_nonce' ); ?>
     1312                                <?php if ( $has_consent ) : ?>
     1313                                        <input type="hidden" name="plugin_tracker_consent_action" value="revoke" />
     1314                                        <button type="submit" class="button button-secondary" onclick="return confirm('<?php echo esc_js( __( 'Revoke data sharing and stop all future reports to Plugin Tracker?', 'easy-php-settings' ) ); ?>');">
     1315                                                <?php esc_html_e( 'Revoke consent', 'easy-php-settings' ); ?>
     1316                                        </button>
     1317                                <?php else : ?>
     1318                                        <input type="hidden" name="plugin_tracker_consent_action" value="grant" />
     1319                                        <button type="submit" class="button button-primary">
     1320                                                <?php esc_html_e( 'Allow data sharing', 'easy-php-settings' ); ?>
     1321                                        </button>
     1322                                <?php endif; ?>
     1323                        </form>
     1324                <?php endif; ?>
     1325        </div>
     1326        <?php
     1327}
  • easy-php-settings/trunk/readme.txt

    r3580062 r3672709  
    55Requires at least: 5.0
    66Tested up to: 7.0
    7 Stable tag: 1.1.6
     7Stable tag: 1.1.7
    88Requires PHP: 7.2
    99License: GPLv2 or later
    … …  
    3636This plugin is perfect for developers and site administrators who want a quick and safe way to view and adjust their site's technical settings.
    3737
    38 **Privacy & usage data:**
    39 
    40 On activation and periodically while active, Easy PHP Settings sends basic site information to the developer to improve plugin services: site URL, WordPress/PHP/plugin versions, server software, admin email, and lists of installed plugins and themes. An informational admin notice explains this on first use; see the About tab for full details.
     38**Privacy & data sharing:**
     39
     40Easy PHP Settings includes an **optional**, **default-off** integration with Plugin Tracker (CodeEyes) at https://plugin.codereyes.com/. **No data is sent until an administrator explicitly opts in** from the About tab or the optional admin notice.
     41
     42If you opt in, the following may be transmitted: site URL; WordPress, PHP, and plugin versions; server software; administrator email and display name; and lists of installed plugins and themes (name, version, active status). Data is sent once when you opt in, then at most once per week (scheduled task), at most once per hour during admin use, after plugin updates, and once on deactivation if you had opted in. Purpose: improve plugin support and related services/offers.
     43
     44You can revoke consent at any time under **Tools → Easy PHP Settings → About → Privacy & Data Sharing**. The plugin works fully without enabling data sharing. See the **Privacy Policy** section below for full details.
    4145
    4246== Pro Features ==
    … …  
    1241284. Extensions — View all loaded PHP extensions by category with missing extension alerts.
    1251295. Status — Live comparison of current vs. recommended PHP and WordPress memory values.
    126 6. About — Plugin information, author details, and support links.
     1306. About — Plugin information, privacy & data sharing controls, author details, and support links.
     131
     132== Privacy Policy ==
     133
     134This plugin can optionally send site information to a third-party service when an administrator explicitly opts in. **Data sharing is disabled by default.**
     135
     136**Third-party service:** Plugin Tracker (CodeEyes) — https://plugin.codereyes.com/
     137
     138**Data that may be sent after opt-in:**
     139* Site URL
     140* WordPress, PHP, and Easy PHP Settings plugin versions
     141* Server software
     142* Administrator email address and display name
     143* Installed plugins and themes (name, version, active status)
     144
     145**When data is sent:** Once when you opt in; then at most once per week via a scheduled task; at most once per hour during admin dashboard use; after plugin updates; and once on plugin deactivation if you had opted in.
     146
     147**Purpose:** Improve plugin support, service updates, and optional offers from the developer.
     148
     149**How to enable or revoke:** Go to **Tools → Easy PHP Settings → About → Privacy & Data Sharing**. Use **Allow data sharing** to opt in or **Revoke consent** to stop all future transmission and clear scheduled sync tasks.
     150
     151**No data before opt-in:** Activating or using Easy PHP Settings does not send any information to plugin.codereyes.com until you explicitly allow it.
    127152
    128153== Changelog ==
     154
     155= 1.1.7 =
     156Released: August 30, 2026
     157
     158* Fixed: WordPress.org Guideline 7 compliance — all communication with plugin.codereyes.com is gated behind explicit, default-off administrator opt-in.
     159* Added: Opt-in admin notice with full disclosure and Allow / No thanks actions; About tab privacy panel with enable and revoke controls.
     160* Added: Suggested privacy policy content via wp_add_privacy_policy_content().
     161* Changed: Plugin activation no longer sends install reports or schedules tracker cron until consent is granted.
     162* Changed: Dashboard offers widget, offer notices, and external offer images load only after opt-in.
     163* Updated: Readme privacy documentation to accurately describe optional data sharing.
    129164
    130165= 1.1.6 =
    … …  
    135170* Improved: PHP Settings table with search toolbar, status badges, select-all, and copy-selected actions.
    136171* Improved: Advanced Tools section combining Configuration Generator, Test Settings, and Danger Zone into a unified grid layout.
    137 * Added: Dashboard widget offers displayed as post-style cards with images from the plugin tracker API.
    138 * Added: 7-day countdown admin notice for new tracker offers with dismiss and snooze actions.
    139 * Fixed: Plugin tracker restores install reporting without opt-in, full payload (admin email, plugins, themes), and blocking install requests.
    140 * Fixed: Deactivation hook reports uninstalls and clears scheduled tracker pings.
    141 * Improved: Tracker offer cache refresh and hourly admin sync for up-to-date dashboard data.
     172* Added: Dashboard widget offers displayed as post-style cards with images from the plugin tracker API (requires opt-in as of 1.1.7).
     173* Added: 7-day countdown admin notice for new tracker offers with dismiss and snooze actions (requires opt-in as of 1.1.7).
     174* Improved: Tracker offer cache refresh and hourly admin sync for up-to-date dashboard data (requires opt-in as of 1.1.7).
    142175
    143176= 1.1.5 =
    … …  
    145178
    146179* Added: Admin notice asking the user to leave a 5-star review on WordPress.org after the plugin has been installed for 7 days. Includes "Rate now", "Maybe later" (7-day snooze), and "Already did / Don't show again" actions.
    147 * Fixed: Plugin usage tracker now sends data on activation without requiring opt-in, restores full payload (admin email, plugin/theme inventory), and uses blocking requests for reliable install reporting.
    148 * Fixed: Tracker deactivation hook reports uninstalls and clears scheduled pings.
    149 * Improved: Hourly admin sync keeps tracker dashboard data up to date between weekly cron pings.
     180* Note: Tracker behavior in 1.1.5 was superseded by explicit opt-in requirements in 1.1.7.
    150181
    151182= 1.1.4 =
    … …  
    242273== Upgrade Notice ==
    243274
     275= 1.1.7 =
     276Restores WordPress.org compliance: optional data sharing with plugin.codereyes.com is disabled by default and requires explicit administrator opt-in. No outbound tracker requests until you allow it from the About tab.
     277
    244278= 1.1.6 =
    245279Major admin UI refresh with redesigned settings pages, improved save experience, Advanced Tools section, and enhanced plugin tracker dashboard offers.
  • easy-php-settings/trunk/uninstall.php

    r3580041 r3672709  
    8787);
    8888
    89 // Plugin Tracker integration: cron, consent state, and options.
     89// Plugin Tracker integration: deactivate ping if opted in, then remove all tracker data.
     90$tracker_file     = dirname( __FILE__ ) . '/includes/plugin-tracker-integration.php';
    9091$main_plugin_file = dirname( __FILE__ ) . '/class-easy-php-settings.php';
    91 $basename        = plugin_basename( $main_plugin_file );
    92 $cron_option     = 'plugin_tracker_cron_' . md5( $basename );
    93 $hook_name       = 'plugin_tracker_ping_' . preg_replace( '/[^a-z0-9_-]/i', '_', $basename );
    9492
    95 wp_clear_scheduled_hook( $hook_name );
    96 delete_option( $cron_option );
    97 delete_option( 'plugin_tracker_plugin_file' );
    98 delete_option( 'plugin_tracker_consent' );
    99 delete_option( 'plugin_tracker_consent_time' );
    100 delete_option( 'plugin_tracker_known_offer_ids' );
    101 delete_option( 'plugin_tracker_offer_notices' );
     93if ( file_exists( $tracker_file ) ) {
     94        require_once $tracker_file;
    10295
    103 // Best-effort: notify a denied state so the tracker can stop sending.
    104 $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => 'plugin_tracker_notice_dismissed' ) );
     96        $had_consent = '1' === get_option( 'plugin_tracker_consent', '0' );
     97        $plugin_file = get_option( 'plugin_tracker_plugin_file', $main_plugin_file );
    10598
    106 // Plugin Tracker transients.
    107 $wpdb->query(
    108         $wpdb->prepare(
    109                 "DELETE FROM $wpdb->options WHERE option_name LIKE %s OR option_name LIKE %s",
    110                 $wpdb->esc_like( '_transient_plugin_tracker_' ) . '%',
    111                 $wpdb->esc_like( '_transient_timeout_plugin_tracker_' ) . '%'
    112         )
    113 );
     99        if ( $had_consent && $plugin_file && function_exists( 'tracker_integration_report_deactivate' ) ) {
     100                tracker_integration_report_deactivate( $plugin_file );
     101        }
     102
     103        if ( function_exists( 'tracker_integration_cleanup' ) ) {
     104                tracker_integration_cleanup( $main_plugin_file );
     105        }
     106} else {
     107        $basename    = plugin_basename( $main_plugin_file );
     108        $cron_option = 'plugin_tracker_cron_' . md5( $basename );
     109        $hook_name   = 'plugin_tracker_ping_' . preg_replace( '/[^a-z0-9_-]/i', '_', $basename );
     110
     111        wp_clear_scheduled_hook( $hook_name );
     112        delete_option( $cron_option );
     113        delete_option( 'plugin_tracker_plugin_file' );
     114        delete_option( 'plugin_tracker_consent' );
     115        delete_option( 'plugin_tracker_consent_time' );
     116        delete_option( 'plugin_tracker_known_offer_ids' );
     117        delete_option( 'plugin_tracker_offer_notices' );
     118
     119        $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => 'plugin_tracker_optin_dismissed' ) );
     120
     121        $wpdb->query(
     122                $wpdb->prepare(
     123                        "DELETE FROM $wpdb->options WHERE option_name LIKE %s OR option_name LIKE %s",
     124                        $wpdb->esc_like( '_transient_plugin_tracker_' ) . '%',
     125                        $wpdb->esc_like( '_transient_timeout_plugin_tracker_' ) . '%'
     126                )
     127        );
     128}
Note: See TracChangeset for help on using the changeset viewer.