'; return; } $score = $summary['score']; ?>

|WP_Error */ public static function summary() { $cached = get_transient( self::SUMMARY_CACHE ); if ( is_array( $cached ) ) { return $cached; } $response = ( new ConsivaClient() )->get_dashboard_summary(); if ( is_wp_error( $response ) ) { return $response; } $body = $response['body']; $r = isset( $body['readiness'] ) && is_array( $body['readiness'] ) ? $body['readiness'] : array(); $factors = array(); foreach ( isset( $r['factors'] ) && is_array( $r['factors'] ) ? $r['factors'] : array() as $f ) { if ( is_array( $f ) && isset( $f['label'], $f['max'] ) ) { $factors[] = array( 'label' => sanitize_text_field( (string) $f['label'] ), 'points' => isset( $f['points'] ) ? max( 0, (int) $f['points'] ) : 0, 'max' => max( 0, (int) $f['max'] ), 'explanation' => isset( $f['explanation'] ) ? sanitize_text_field( (string) $f['explanation'] ) : '', ); } } $movers = array(); foreach ( isset( $r['top_movers'] ) && is_array( $r['top_movers'] ) ? array_slice( $r['top_movers'], 0, 3 ) : array() as $m ) { if ( is_array( $m ) && isset( $m['label'] ) ) { $movers[] = array( 'label' => sanitize_text_field( (string) $m['label'] ), 'points' => isset( $m['potential_points'] ) ? max( 0, (int) $m['potential_points'] ) : 0, 'explanation' => isset( $m['explanation'] ) ? sanitize_text_field( (string) $m['explanation'] ) : '', ); } } $counts = isset( $body['counts'] ) && is_array( $body['counts'] ) ? $body['counts'] : array(); $method = isset( $r['methodology_url'] ) ? esc_url_raw( (string) $r['methodology_url'], array( 'https' ) ) : ''; $method = Endpoints::is_consiva_link( $method ) ? $method : ''; // Only links to Consiva (§9.3). $summary = array( 'score' => isset( $r['score'] ) ? max( 0, min( 100, (int) $r['score'] ) ) : 0, 'factors' => $factors, 'movers' => $movers, 'methodology_url' => $method, 'consent_events' => isset( $counts['consent_events_30d'] ) ? max( 0, (int) $counts['consent_events_30d'] ) : 0, 'evidence' => isset( $counts['evidence_artefacts'] ) ? max( 0, (int) $counts['evidence_artefacts'] ) : 0, ); set_transient( self::SUMMARY_CACHE, $summary, self::CACHE_TTL ); return $summary; } // ------------------------------------------------------------------ Recommendations /** * @return void */ public static function render_recommendations() { if ( ! Availability::has( Availability::RECOMMENDATIONS ) ) { return; // The recommendations routes are not built yet. } $recs = self::recommendations(); if ( is_wp_error( $recs ) ) { echo ''; return; } if ( ! $recs ) { return; // Nothing to do: no empty panel. } ?> $rec Recommendation. * @return void */ private static function render_rec_action( array $rec ) { if ( 'one_click' === $rec['type'] && Capabilities::can_configure() ) { ?>
'consiva-consent-apply-' . sanitize_html_class( $rec['id'] ) ) ); ?>
' . esc_html__( 'Review the items', 'consiva-ai' ) . '

'; return; } if ( '' !== $rec['instructions'] ) { echo '

' . esc_html( $rec['instructions'] ) . '

'; } // WordPress-specific shortcut for recommendations whose fix lives in WordPress itself. if ( 'link_privacy_policy' === $rec['code'] ) { echo '

' . esc_html__( 'Open Settings → Privacy', 'consiva-ai' ) . '

'; } } /** * Allowlisted open recommendations, cached. * * @return array>|WP_Error */ public static function recommendations() { $cached = get_transient( self::RECS_CACHE ); if ( is_array( $cached ) ) { return $cached; } $response = ( new ConsivaClient() )->get_recommendations(); if ( is_wp_error( $response ) ) { return $response; } $out = array(); foreach ( isset( $response['body']['data'] ) && is_array( $response['body']['data'] ) ? $response['body']['data'] : array() as $r ) { if ( ! is_array( $r ) || ! isset( $r['recommendation_id'], $r['title'] ) || ! preg_match( ScanProgress::ID_PATTERN, (string) $r['recommendation_id'] ) ) { continue; } $out[] = array( 'id' => (string) $r['recommendation_id'], 'code' => isset( $r['code'] ) ? sanitize_key( (string) $r['code'] ) : '', 'title' => sanitize_text_field( (string) $r['title'] ), 'rationale' => isset( $r['rationale'] ) ? sanitize_text_field( (string) $r['rationale'] ) : '', 'type' => isset( $r['action_type'] ) && in_array( $r['action_type'], array( 'one_click', 'guided', 'manual' ), true ) ? $r['action_type'] : 'manual', 'impact' => isset( $r['impact'] ) && in_array( $r['impact'], array( 'high', 'medium', 'low' ), true ) ? $r['impact'] : 'medium', 'instructions' => isset( $r['proposed_action']['instructions'] ) && is_string( $r['proposed_action']['instructions'] ) ? sanitize_text_field( $r['proposed_action']['instructions'] ) : '', ); } $order = array( 'high' => 0, 'medium' => 1, 'low' => 2, ); usort( $out, static function ( $a, $b ) use ( $order ) { return $order[ $a['impact'] ] - $order[ $b['impact'] ]; } ); set_transient( self::RECS_CACHE, $out, self::CACHE_TTL ); return $out; } /** * One-click apply: Consiva changes the config and, on an active site, publishes it. * * @return void */ public function handle_apply() { if ( ! current_user_can( Onboarding::CAPABILITY ) ) { wp_die( esc_html__( 'You do not have permission to change the Consiva setup.', 'consiva-ai' ), '', array( 'response' => 403 ) ); } check_admin_referer( self::ACTION_APPLY ); $id = isset( $_POST['recommendation'] ) ? sanitize_text_field( wp_unslash( $_POST['recommendation'] ) ) : ''; if ( ! preg_match( ScanProgress::ID_PATTERN, $id ) ) { wp_safe_redirect( Screens::url() ); exit; } $result = ( new ConsivaClient() )->apply_recommendation( $id ); self::clear_cache(); if ( is_wp_error( $result ) ) { Notices::push_error( $result ); wp_safe_redirect( Screens::url() ); exit; } $version = isset( $result['body']['consent_config']['config_version'] ) ? (int) $result['body']['consent_config']['config_version'] : 0; if ( $version > (int) State::get( 'config_version' ) ) { State::update( array( 'config_version' => $version ) ); SetupScreen::refresh_front_end(); } Notices::push( 'success', $version /* translators: %d: configuration version number. */ ? sprintf( __( 'Applied and published as configuration version %d.', 'consiva-ai' ), $version ) : __( 'Applied.', 'consiva-ai' ), $result['request_id'] ); wp_safe_redirect( Screens::url() ); exit; } /** * @param string $impact high|medium|low. * @return string */ private static function impact_label( $impact ) { $labels = array( 'high' => __( 'High impact', 'consiva-ai' ), 'medium' => __( 'Medium impact', 'consiva-ai' ), 'low' => __( 'Low impact', 'consiva-ai' ), ); return $labels[ $impact ]; } // ------------------------------------------------------------------ Verification (WP-F10) /** * Verification results (Plugin §6.4, WP-F10). * * @return void */ public static function render_verification() { $view = Verification::current(); ?> '; return; } if ( 'none' === $view['status'] ) { echo '

' . esc_html__( 'Verification', 'consiva-ai' ) . '

'; echo '

' . esc_html__( 'Consiva checks that your banner really blocks trackers each time you activate or publish consent controls. No verification has run yet.', 'consiva-ai' ) . '

'; return; } if ( ! $view['done'] ) { ?>

$row Result row. * @return bool */ public static function is_conflict( $row ) { return 'fires_pre_consent_CONFLICT' === $row['state']; } /** * @param array $row Result row. * @return bool */ public static function is_not_conflict( $row ) { return ! self::is_conflict( $row ); } /** * @param string $state Verification state. * @return string */ private static function state_label( $state ) { switch ( $state ) { case 'verified_fires_only_after_consent': return __( 'Waits for consent', 'consiva-ai' ); case 'verified_blocked': return __( 'Blocked in every case', 'consiva-ai' ); default: return __( 'Not seen during the check, so not tested', 'consiva-ai' ); } } /** * @param string $category Category code. * @return void */ private static function category_chip( $category ) { $labels = array( 'necessary' => __( 'Necessary', 'consiva-ai' ), 'preferences' => __( 'Preferences', 'consiva-ai' ), 'statistics' => __( 'Statistics', 'consiva-ai' ), 'marketing' => __( 'Marketing', 'consiva-ai' ), ); if ( isset( $labels[ $category ] ) ) { echo ' ' . esc_html( $labels[ $category ] ) . ' '; } } }