' . esc_html__( 'Privacy Readiness', 'consiva-ai' ) . '';
Screens::render_error( $summary );
echo '
';
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 '' . esc_html__( 'Recommendations', 'consiva-ai' ) . '
';
Screens::render_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() ) {
?>
' . 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();
?>
' . esc_html__( 'Verification', 'consiva-ai' ) . '';
Screens::render_error( $view );
echo '
';
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 ] ) . ' ';
}
}
}