| @@ -45,27 +45,37 @@ | ||
| 45 | 45 | public const CONSENT_COOKIE = 'xspeed_ai_consent'; |
| 46 | 46 | |
| 47 | 47 | public function ui_metadata(): array { |
| 48 | 48 | return array( |
| 49 | - 'label' => 'AI Privacy', | |
| 49 | + 'label' => __( 'AI Privacy', 'xspeed' ), | |
| 50 | 50 | 'icon' => 'Shield', |
| 51 | - 'description' => 'Govern whether AI-powered features (Pro) may collect data from your visitors. The off-switch is here in Free because privacy is a fundamental right, not a paid feature.', | |
| 51 | + 'description' => __( 'Govern whether AI-powered features (Pro) may collect data from your visitors. The off-switch is here in Free because privacy is a fundamental right, not a paid feature.', 'xspeed' ), | |
| 52 | 52 | ); |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | + /** | |
| 56 | + * @inheritDoc | |
| 57 | + * | |
| 58 | + * OFF here would mean asking for less consent than the user configured, which | |
| 59 | + * is the one direction this profile must never move. | |
| 60 | + */ | |
| 61 | + public function conflict_safe_exempt(): array { | |
| 62 | + return array( 'gdpr_consent_required' ); | |
| 63 | + } | |
| 64 | + | |
| 55 | 65 | public function settings_schema(): array { |
| 56 | 66 | return array( |
| 57 | 67 | 'gdpr_consent_required' => array( |
| 58 | 68 | 'type' => 'bool', |
| 59 | 69 | 'default' => true, |
| 60 | - 'label' => 'Require consent before AI data collection', | |
| 61 | - 'description' => 'When ON, AI-powered features only record data after a visitor accepts the consent banner. When OFF, they collect from every visitor — only legal in regions without GDPR-style consent rules. The setting applies even if Pro is not installed (so a later Pro upgrade respects whichever choice you made).', | |
| 70 | + 'label' => __( 'Require consent before AI data collection', 'xspeed' ), | |
| 71 | + 'description' => __( 'When ON, AI-powered features only record data after a visitor accepts the consent banner. When OFF, they collect from every visitor — only legal in regions without GDPR-style consent rules. The setting applies even if Pro is not installed (so a later Pro upgrade respects whichever choice you made).', 'xspeed' ), | |
| 62 | 72 | ), |
| 63 | 73 | 'consent_banner_text' => array( |
| 64 | 74 | 'type' => 'string', |
| 65 | 75 | 'default' => 'We collect anonymized navigation and performance data to make this site faster. Accept to help us optimize your experience.', |
| 66 | - 'label' => 'Consent banner text', | |
| 67 | - 'description' => 'Shown in the cookie consent banner. Keep it factual — what you collect (page navigation, performance metrics) and why.', | |
| 76 | + 'label' => __( 'Consent banner text', 'xspeed' ), | |
| 77 | + 'description' => __( 'Shown in the cookie consent banner. Keep it factual — what you collect (page navigation, performance metrics) and why.', 'xspeed' ), | |
| 68 | 78 | ), |
| 69 | 79 | ); |
| 70 | 80 | } |
| 71 | 81 | |
| @@ -101,8 +111,9 @@ | ||
| 101 | 111 | array( |
| 102 | 112 | 'name' => 'xspeed ai-privacy', |
| 103 | 113 | 'callback' => array( $this, 'cli_handler' ), |
| 104 | 114 | 'shortdesc' => 'Show whether AI data collection is allowed for the current request context (CLI = no cookie).', |
| 115 | + 'ai_hint' => 'May xSpeed send this site\'s data to an AI provider? Check before invoking any AI-backed feature — it reports the user\'s opt-in state, not a setting to change casually.', | |
| 105 | 116 | 'synopsis' => array(), |
| 106 | 117 | ), |
| 107 | 118 | ); |
| 108 | 119 | } |