PluginProbe
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification / 5.5.0
Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification v5.5.0
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 3.0.70 3.0.71 3.0.72 All 35 releases
double-opt-in / src / Licensing / AddonLicenseRegistry.php

AddonLicenseRegistry.php in Double Opt-In for Contact Form 7 – Secure, GDPR-Compliant Email Verification 5.5.0, at src/Licensing/AddonLicenseRegistry.php

198 lines 3.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Addon License Registry
4 *
5 * @package Forge12\DoubleOptIn\Licensing
6 * @since 4.3.0
7 */
8
9 namespace Forge12\DoubleOptIn\Licensing;
10
11 use Forge12\Shared\LoggerInterface;
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 /**
18 * Class AddonLicenseRegistry
19 *
20 * In-memory, request-scoped state store for addon license entitlements.
21 *
22 * Entitlements are populated by license providers during their own boot
23 * cycle. Because the registry is in-memory only, providers must re-grant
24 * entitlements on every request. This is deliberate: it avoids stale
25 * cached entitlements surviving a license revocation, and it keeps the
26 * registry simple.
27 *
28 * Providers that need persistence (to avoid calling an update server on
29 * every request) are responsible for their own caching (transients,
30 * options) and re-grant the entitlements on each bootstrap from cache.
31 */
32 final class AddonLicenseRegistry implements AddonLicenseRegistryInterface {
33
34 /**
35 * Singleton instance.
36 *
37 * @var AddonLicenseRegistry|null
38 */
39 private static ?AddonLicenseRegistry $instance = null;
40
41 /**
42 * Licensed addons, keyed by addon ID, values are provider sources.
43 *
44 * @var array<string, string>
45 */
46 private array $entitlements = array();
47
48 /**
49 * Logger instance.
50 *
51 * @var LoggerInterface|null
52 */
53 private ?LoggerInterface $logger = null;
54
55 /**
56 * Private constructor — use {@see getInstance()}.
57 */
58 private function __construct() {}
59
60 /**
61 * Prevent cloning.
62 */
63 private function __clone() {}
64
65 /**
66 * Prevent unserialization.
67 *
68 * @throws \Exception
69 */
70 public function __wakeup() {
71 throw new \Exception( 'Cannot unserialize singleton' );
72 }
73
74 /**
75 * Get the singleton instance.
76 *
77 * @return AddonLicenseRegistry
78 */
79 public static function getInstance(): AddonLicenseRegistry {
80 if ( self::$instance === null ) {
81 self::$instance = new self();
82 }
83 return self::$instance;
84 }
85
86 /**
87 * Reset the singleton. Tests only.
88 *
89 * @internal
90 * @return void
91 */
92 public static function resetInstance(): void {
93 self::$instance = null;
94 }
95
96 /**
97 * Set the logger.
98 *
99 * @param LoggerInterface $logger The logger.
100 * @return void
101 */
102 public function setLogger( LoggerInterface $logger ): void {
103 $this->logger = $logger;
104 }
105
106 /**
107 * {@inheritdoc}
108 */
109 public function grant( string $addonId, string $source = 'default' ): void {
110 $this->entitlements[ $addonId ] = $source;
111
112 $this->log(
113 'info',
114 'License granted',
115 array(
116 'addon_id' => $addonId,
117 'source' => $source,
118 )
119 );
120 }
121
122 /**
123 * {@inheritdoc}
124 */
125 public function revoke( string $addonId ): void {
126 if ( ! isset( $this->entitlements[ $addonId ] ) ) {
127 return;
128 }
129
130 unset( $this->entitlements[ $addonId ] );
131
132 $this->log(
133 'info',
134 'License revoked',
135 array(
136 'addon_id' => $addonId,
137 )
138 );
139 }
140
141 /**
142 * {@inheritdoc}
143 */
144 public function isLicensed( string $addonId ): bool {
145 return isset( $this->entitlements[ $addonId ] );
146 }
147
148 /**
149 * {@inheritdoc}
150 */
151 public function getSource( string $addonId ): ?string {
152 return $this->entitlements[ $addonId ] ?? null;
153 }
154
155 /**
156 * {@inheritdoc}
157 */
158 public function getLicensedAddons(): array {
159 return array_keys( $this->entitlements );
160 }
161
162 /**
163 * Log a message through the configured logger, if any.
164 *
165 * @param string $level Log level.
166 * @param string $message Message.
167 * @param array $context Context.
168 * @return void
169 */
170 private function log( string $level, string $message, array $context = array() ): void {
171 if ( $this->logger === null ) {
172 return;
173 }
174
175 $context = array_merge(
176 array(
177 'plugin' => 'double-opt-in',
178 'component' => 'addon-license-registry',
179 ),
180 $context
181 );
182
183 switch ( $level ) {
184 case 'error':
185 $this->logger->error( $message, $context );
186 break;
187 case 'warning':
188 $this->logger->warning( $message, $context );
189 break;
190 case 'info':
191 $this->logger->info( $message, $context );
192 break;
193 default:
194 $this->logger->debug( $message, $context );
195 }
196 }
197 }
198