| 1 |
<?php |
| 2 |
|
| 3 |
namespace gVectors\News\Services; |
| 4 |
|
| 5 |
use gVectors\News\Config; |
| 6 |
use gVectors\News\NewsModule; |
| 7 |
|
| 8 |
// Exit if accessed directly |
| 9 |
if( ! defined( 'ABSPATH' ) ) exit; |
| 10 |
|
| 11 |
/** |
| 12 |
* Explicit opt-in gate (WordPress.org Guideline 7). |
| 13 |
* |
| 14 |
* Shows a one-time notice to users who can activate plugins, explaining what |
| 15 |
* connects to the gVectors server and what data is sent. Until the admin |
| 16 |
* clicks [Enable], no proxy HTTP request is made by this module. |
| 17 |
*/ |
| 18 |
class ConsentService { |
| 19 |
private $config; |
| 20 |
|
| 21 |
public function __construct( Config $config ) { |
| 22 |
$this->config = $config; |
| 23 |
add_action( 'admin_notices', [ $this, 'render_optin_notice' ] ); |
| 24 |
add_action( 'wp_ajax_' . $this->config->get_prefix() . 'news_optin', [ $this, 'ajax_optin' ] ); |
| 25 |
add_action( 'wp_ajax_' . $this->config->get_prefix() . 'news_settings', [ $this, 'ajax_settings' ] ); |
| 26 |
} |
| 27 |
|
| 28 |
public function is_enabled(): bool { |
| 29 |
return (bool) get_option( $this->config->get_service_enabled_option(), false ); |
| 30 |
} |
| 31 |
|
| 32 |
public function should_show_optin_notice(): bool { |
| 33 |
return ! $this->is_enabled() |
| 34 |
&& ! get_option( $this->config->get_optin_notice_dismissed_option(), false ) |
| 35 |
&& current_user_can( 'activate_plugins' ); |
| 36 |
} |
| 37 |
|
| 38 |
/** |
| 39 |
* First-activation opt-in notice: what connects, what is sent, why. |
| 40 |
*/ |
| 41 |
public function render_optin_notice(): void { |
| 42 |
if( ! NewsModule::is_notice_page() ) return; |
| 43 |
if( ! $this->should_show_optin_notice() ) return; |
| 44 |
?> |
| 45 |
<div class="notice notice-info gvectors-news-optin"> |
| 46 |
<p> |
| 47 |
<strong><?php esc_html_e( 'Enable addon news & license reminders?', 'gvectors' ); ?></strong> |
| 48 |
</p> |
| 49 |
<p> |
| 50 |
<?php esc_html_e( 'Get notified about new addons, new features and expiring addon licenses. When enabled, this site connects to the gVectors server once a day and sends: your site address, an anonymous site identifier (a hash), and the slugs and versions of installed gVectors addons. No personal data, email addresses or content is ever sent.', 'gvectors' ); ?> |
| 51 |
<?php |
| 52 |
printf( |
| 53 |
/* translators: %s: link to the News & Emails settings page */ |
| 54 |
esc_html__( 'You can change this decision or manage email preferences anytime on the %s page.', 'gvectors' ), |
| 55 |
'<a href="' . esc_url( $this->config->get_settings_page_url() ) . '">' . esc_html__( 'News & Emails', 'gvectors' ) . '</a>' |
| 56 |
); |
| 57 |
?> |
| 58 |
<a href="<?php echo esc_url( $this->config->get_privacy_policy_url() ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Privacy policy', 'gvectors' ); ?></a> |
| 59 |
</p> |
| 60 |
<p> |
| 61 |
<button type="button" class="button button-primary gvectors-news-optin-enable"><?php esc_html_e( 'Enable', 'gvectors' ); ?></button> |
| 62 |
<button type="button" class="button gvectors-news-optin-later"><?php esc_html_e( 'Not now', 'gvectors' ); ?></button> |
| 63 |
</p> |
| 64 |
</div> |
| 65 |
<?php |
| 66 |
} |
| 67 |
|
| 68 |
/** |
| 69 |
* AJAX: [Enable] / [Not now] on the opt-in notice. |
| 70 |
*/ |
| 71 |
public function ajax_optin(): void { |
| 72 |
check_ajax_referer( $this->config->get_nonce_action(), 'nonce' ); |
| 73 |
if( ! current_user_can( 'activate_plugins' ) ) { |
| 74 |
wp_send_json_error( [ 'message' => 'Permission denied' ], 403 ); |
| 75 |
} |
| 76 |
|
| 77 |
$enable = ! empty( $_POST['enable'] ); |
| 78 |
if( $enable ) { |
| 79 |
update_option( $this->config->get_service_enabled_option(), true ); |
| 80 |
// First sync right away so news/reminders appear without waiting a day |
| 81 |
if( ! wp_next_scheduled( $this->config->get_cron_hook() ) ) { |
| 82 |
wp_schedule_single_event( time() + 10, $this->config->get_cron_hook() ); |
| 83 |
} |
| 84 |
} |
| 85 |
update_option( $this->config->get_optin_notice_dismissed_option(), true ); |
| 86 |
|
| 87 |
wp_send_json_success( [ 'enabled' => $enable ] ); |
| 88 |
} |
| 89 |
|
| 90 |
/** |
| 91 |
* AJAX: master service switch toggle. Category-level control lives in the |
| 92 |
* PrefsService matrices, managed from the News & Emails settings page. |
| 93 |
*/ |
| 94 |
public function ajax_settings(): void { |
| 95 |
check_ajax_referer( $this->config->get_nonce_action(), 'nonce' ); |
| 96 |
if( ! current_user_can( 'activate_plugins' ) ) { |
| 97 |
wp_send_json_error( [ 'message' => 'Permission denied' ], 403 ); |
| 98 |
} |
| 99 |
|
| 100 |
if( isset( $_POST['service_enabled'] ) ) { |
| 101 |
update_option( $this->config->get_service_enabled_option(), (bool) (int) $_POST['service_enabled'] ); |
| 102 |
} |
| 103 |
|
| 104 |
wp_send_json_success( [ 'service_enabled' => $this->is_enabled() ] ); |
| 105 |
} |
| 106 |
} |
| 107 |
|