PluginProbe
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification / 5.6.1
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification v5.6.1
5.6.2 5.6.3 5.6.1 5.6.0 5.5.0 5.4.0 5.3.2 5.3.1 5.1.6 5.1.5 trunk 2.1.5 2.11 2.12 2.13 2.15 3.0.0 3.0.1 3.0.2 3.0.3 3.0.5 3.0.51 3.0.60 3.0.61 3.0.62 All 38 releases
double-opt-in / src / Migration / GrandfatherLicenseClient.php

GrandfatherLicenseClient.php in Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification 5.6.1, at src/Migration/GrandfatherLicenseClient.php

121 lines 3.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Grandfather License Client
4 *
5 * HTTP client wrapper around `POST /v1/license/grandfather/avada` on
6 * api.forge12.com. Used by {@see AvadaDeprecationNotice} when a site
7 * admin clicks "Claim free grandfather license" on the migration notice.
8 *
9 * Intentionally thin — no retries, no caching beyond the immediate result.
10 * Callers persist the returned license key; repeated calls for the same
11 * site return `already_claimed` from the server and are safe.
12 *
13 * @package Forge12\DoubleOptIn\Migration
14 * @since 4.99.0
15 */
16
17 namespace Forge12\DoubleOptIn\Migration;
18
19 if ( ! defined( 'ABSPATH' ) ) {
20 exit;
21 }
22
23 final class GrandfatherLicenseClient {
24
25 private const ENDPOINT_URL = 'https://api.forge12.com/v1/license/grandfather/avada';
26 private const TIMEOUT = 15;
27
28 /**
29 * Attempt to claim a grandfather license for this site.
30 *
31 * @param string $siteUrl Canonical site URL (`home_url()`).
32 * @param string $adminEmail Site admin email for records.
33 * @param array<string, mixed> $attestation Self-reported attestation block.
34 * @return array{
35 * success: bool,
36 * status: string,
37 * licenseKey: string,
38 * message: string
39 * }
40 */
41 public function claimAvada( string $siteUrl, string $adminEmail, array $attestation ): array {
42 $response = wp_remote_post(
43 self::ENDPOINT_URL,
44 array(
45 'timeout' => self::TIMEOUT,
46 'headers' => array( 'Content-Type' => 'application/json' ),
47 'body' => wp_json_encode(
48 array(
49 'siteUrl' => $siteUrl,
50 'adminEmail' => $adminEmail,
51 'attestation' => $attestation,
52 )
53 ),
54 )
55 );
56
57 if ( is_wp_error( $response ) ) {
58 return array(
59 'success' => false,
60 'status' => 'network_error',
61 'licenseKey' => '',
62 'message' => $response->get_error_message(),
63 );
64 }
65
66 $statusCode = wp_remote_retrieve_response_code( $response );
67 $body = json_decode( wp_remote_retrieve_body( $response ), true );
68
69 if ( ! is_array( $body ) ) {
70 return array(
71 'success' => false,
72 'status' => 'bad_response',
73 'licenseKey' => '',
74 'message' => __( 'Server returned an unreadable response.', 'double-opt-in' ),
75 );
76 }
77
78 // Cutoff expired → HTTP 410 with { status: 'cutoff_expired', message }
79 if ( $statusCode === 410 ) {
80 return array(
81 'success' => false,
82 'status' => $body['status'] ?? 'cutoff_expired',
83 'licenseKey' => '',
84 'message' => $body['message'] ?? __( 'The claim window has closed.', 'double-opt-in' ),
85 );
86 }
87
88 // Already claimed → HTTP 200 with { issued: false, status: 'already_claimed' }
89 if ( isset( $body['status'] ) && $body['status'] === 'already_claimed' ) {
90 return array(
91 'success' => false,
92 'status' => 'already_claimed',
93 'licenseKey' => '',
94 'message' => $body['message'] ?? __( 'A grandfather license was already issued for this site.', 'double-opt-in' ),
95 );
96 }
97
98 // Happy path → { issued: true, licenseKey, licenseType, validUntil }
99 if ( ! empty( $body['issued'] ) && ! empty( $body['licenseKey'] ) ) {
100 return array(
101 'success' => true,
102 'status' => 'issued',
103 'licenseKey' => (string) $body['licenseKey'],
104 'message' => sprintf(
105 /* translators: %s: ISO date */
106 __( 'Grandfather license issued, valid until %s.', 'double-opt-in' ),
107 $body['validUntil'] ?? '2099-12-31'
108 ),
109 );
110 }
111
112 // Generic server error (500-ish) with our error shape.
113 return array(
114 'success' => false,
115 'status' => (string) ( $body['errorCode'] ?? 'unknown_error' ),
116 'licenseKey' => '',
117 'message' => (string) ( $body['message'] ?? __( 'Unknown server error.', 'double-opt-in' ) ),
118 );
119 }
120 }
121