Skip to content

Commit 9bee6e2

Browse files
committed
feat: new license implementation for k5
1 parent 15fb706 commit 9bee6e2

File tree

3 files changed

+91
-25
lines changed

3 files changed

+91
-25
lines changed

classes/Support/License.php

Lines changed: 87 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77
use Kirby\Data\Json;
88
use Kirby\Filesystem\F;
99
use Kirby\Http\Remote;
10+
use Kirby\Plugin\License as KirbyLicense;
11+
use Kirby\Plugin\LicenseStatus;
12+
use Kirby\Plugin\Plugin;
1013
use Kirby\Toolkit\Str;
1114

1215
/**
13-
* License management & validation
16+
* DreamForm License implementation for Kirby 5
1417
*
1518
* If you're here to crack the plugin, please buy a license instead.
1619
* I'm an independent developer and this plugin helps fund my open-source work as well.
@@ -20,28 +23,69 @@
2023
* the license validation being too strict, please let me know at [email protected].
2124
* I'm happy to help.
2225
*/
23-
final class License
26+
final class License extends KirbyLicense
2427
{
2528
private const LICENSE_FILE = '.dreamform_license';
2629
private const BASE = "https://plugins.andkindness.com/licenses/";
2730

28-
private function __construct(
29-
protected string|null $license = null,
30-
protected string|null $plugin = null,
31-
protected string|null $edition = null,
32-
protected bool $allowOfflineUse = false,
33-
protected string|null $purchasedOn = null,
34-
protected string|null $assignedUrl = null,
35-
protected string|null $email = null,
36-
protected string|null $signature = null
31+
protected string|null $license = null;
32+
protected string|null $pluginName = null;
33+
protected string|null $edition = null;
34+
protected bool $allowOfflineUse = false;
35+
protected string|null $purchasedOn = null;
36+
protected string|null $assignedUrl = null;
37+
protected string|null $email = null;
38+
protected string|null $signature = null;
39+
40+
public function __construct(
41+
protected Plugin $plugin
3742
) {
43+
$this->name = 'DreamForm License';
44+
45+
// Load license data from disk
46+
$this->loadFromDisk();
47+
$kirby = App::instance();
48+
49+
// Determine status based on existing license validation
50+
if ($this->isValid()) {
51+
$this->status = new LicenseStatus(
52+
value: 'active',
53+
icon: 'check',
54+
label: t('dreamform.license.status.valid'),
55+
theme: 'positive'
56+
);
57+
// No link needed for active license
58+
$this->link = null;
59+
} elseif ($kirby->system()->isLocal()) {
60+
// Local environment - show as demo
61+
$this->status = new LicenseStatus(
62+
value: 'demo',
63+
icon: 'preview',
64+
label: t('dreamform.license.status.demo'),
65+
theme: 'info',
66+
dialog: 'dreamform/activate'
67+
);
68+
// No link, use dialog instead
69+
$this->link = null;
70+
} else {
71+
// Production without valid license
72+
$this->status = new LicenseStatus(
73+
value: 'missing',
74+
icon: 'alert',
75+
label: t('dreamform.license.status.missing'),
76+
theme: 'negative',
77+
dialog: 'dreamform/activate'
78+
);
79+
// No link, use dialog instead
80+
$this->link = null;
81+
}
3882
}
3983

4084
public function licenseData(): array
4185
{
4286
return [
4387
'license' => $this->license,
44-
'plugin' => $this->plugin,
88+
'plugin' => $this->pluginName,
4589
'edition' => $this->edition,
4690
'allowOfflineUse' => $this->allowOfflineUse,
4791
'purchasedOn' => $this->purchasedOn,
@@ -58,29 +102,34 @@ private function signedData(): string
58102

59103
public static function licenseFile(): string
60104
{
61-
return dirname(App::instance()->root('license')) . '/' . License::LICENSE_FILE;
105+
return dirname(App::instance()->root('license')) . '/' . self::LICENSE_FILE;
62106
}
63107

64-
public static function fromDisk(): License
108+
protected function loadFromDisk(): void
65109
{
66110
$licenseFile = static::licenseFile();
67111
if (!F::exists($licenseFile)) {
68-
return new License();
112+
return;
69113
}
70114

71115
try {
72116
$licenseData = Json::read($licenseFile);
117+
foreach ($licenseData as $key => $value) {
118+
// Map 'plugin' to 'pluginName' to avoid conflict with parent property
119+
if ($key === 'plugin') {
120+
$this->pluginName = $value;
121+
} elseif (property_exists($this, $key) && $key !== 'plugin') {
122+
$this->$key = $value;
123+
}
124+
}
73125
} catch (Exception $e) {
74-
return new License();
126+
// Invalid license file
75127
}
76-
77-
return new License(...$licenseData);
78128
}
79129

80130
public function isComplete(): bool
81131
{
82132
return $this->license !== null
83-
&& $this->plugin !== null
84133
&& $this->edition !== null
85134
&& $this->purchasedOn !== null
86135
&& $this->assignedUrl !== null
@@ -128,7 +177,7 @@ public function isValid(): bool
128177
}
129178

130179
$license = Str::lower($this->license);
131-
$request = Remote::post(License::BASE . "{$license}/validate", [
180+
$request = Remote::post(self::BASE . "{$license}/validate", [
132181
'headers' => [
133182
'Content-Type' => 'application/json',
134183
'Accept' => 'application/json',
@@ -158,7 +207,7 @@ public static function normalizeUrl(string $url): string
158207
public static function downloadLicense(string $email, string $license): static
159208
{
160209
$license = Str::lower($license);
161-
$request = Remote::post(License::BASE . "{$license}/download", [
210+
$request = Remote::post(self::BASE . "{$license}/download", [
162211
'headers' => [
163212
'Content-Type' => 'application/json',
164213
'Accept' => 'application/json',
@@ -173,12 +222,25 @@ public static function downloadLicense(string $email, string $license): static
173222
throw new \Exception('Invalid license');
174223
}
175224

176-
$license = new License(...$request->json());
177-
if (!$license->isValid()) {
225+
$licenseData = $request->json();
226+
// Save to disk
227+
Json::write(static::licenseFile(), $licenseData);
228+
229+
// Create new instance with downloaded data
230+
$newLicense = new static(App::instance()->plugin('tobimori/dreamform'));
231+
232+
if (!$newLicense->isValid()) {
178233
throw new \Exception('Downloaded license is invalid');
179234
}
180235

181-
Json::write(static::licenseFile(), $license->licenseData());
182-
return $license;
236+
return $newLicense;
237+
}
238+
239+
/**
240+
* Create a License instance from disk for backwards compatibility
241+
*/
242+
public static function fromDisk(): static
243+
{
244+
return new static(App::instance()->plugin('tobimori/dreamform'));
183245
}
184246
}

index.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
// register plugin
5151
App::plugin(
5252
'tobimori/dreamform',
53+
license: fn (\Kirby\Plugin\Plugin $plugin) => new \tobimori\DreamForm\Support\License($plugin),
5354
extends: [
5455
'api' => require __DIR__ . '/config/api.php',
5556
'options' => require __DIR__ . '/config/options.php',

translations/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@
189189
"license.error.submission": "This site is in demo mode. Submissions are only accepted from logged in users.",
190190
"license.key.help": "You can find your license key after purchasing in the account area of the <a target=\"_blank\" href=\"https://plugins.andkindness.com/account\">Love & Kindness plugin</a> website.",
191191
"license.key.label": "Enter your license key",
192+
"license.status.valid": "Valid license",
193+
"license.status.demo": "Demo",
194+
"license.status.missing": "Missing license",
192195
"settings": "Settings",
193196
"static": "Static",
194197
"submission": "Submission",

0 commit comments

Comments
 (0)