Skip to content

Commit 3c9500b

Browse files
simonhampclaude
andcommitted
Add mobile_min_version to plugins for NativePHP Mobile SDK constraint
Extracts the nativephp/mobile composer requirement during plugin sync and stores it as a dedicated column. Displays it on the public plugin page and in the admin panel. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b69c078 commit 3c9500b

File tree

6 files changed

+169
-0
lines changed

6 files changed

+169
-0
lines changed

app/Filament/Resources/PluginResource.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,11 @@ public static function table(Table $table): Table
242242
})
243243
->sortable(),
244244

245+
Tables\Columns\TextColumn::make('mobile_min_version')
246+
->label('Mobile SDK')
247+
->placeholder('-')
248+
->toggleable(isToggledHiddenByDefault: true),
249+
245250
Tables\Columns\ToggleColumn::make('featured')
246251
->sortable(),
247252

app/Services/PluginSyncService.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ public function sync(Plugin $plugin): bool
8989
$updateData['android_version'] = $this->extractAndroidVersion($nativephpData);
9090
}
9191

92+
if ($composerData) {
93+
$updateData['mobile_min_version'] = $composerData['require']['nativephp/mobile'] ?? null;
94+
}
95+
9296
if ($readme) {
9397
$updateData['readme_html'] = CommonMark::convertToHtml($readme);
9498
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*/
12+
public function up(): void
13+
{
14+
Schema::table('plugins', function (Blueprint $table) {
15+
$table->string('mobile_min_version')->nullable()->after('android_version');
16+
});
17+
}
18+
19+
/**
20+
* Reverse the migrations.
21+
*/
22+
public function down(): void
23+
{
24+
Schema::table('plugins', function (Blueprint $table) {
25+
$table->dropColumn('mobile_min_version');
26+
});
27+
}
28+
};

resources/views/plugin-show.blade.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,14 @@ class="inline-flex items-center gap-1 text-sm font-medium text-indigo-600 hover:
246246
</dd>
247247
</div>
248248

249+
{{-- NativePHP Mobile --}}
250+
<div class="col-span-2 rounded-xl bg-gray-50 p-3 dark:bg-slate-700/30">
251+
<dt class="text-xs font-medium text-gray-500 dark:text-gray-400">NativePHP Mobile</dt>
252+
<dd class="mt-1 text-sm font-medium text-gray-900 dark:text-white">
253+
{{ $plugin->mobile_min_version ?? '' }}
254+
</dd>
255+
</div>
256+
249257
{{-- iOS Version --}}
250258
<div class="rounded-xl bg-gray-50 p-3 dark:bg-slate-700/30">
251259
<dt class="text-xs font-medium text-gray-500 dark:text-gray-400">iOS</dt>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace Tests\Feature;
4+
5+
use App\Features\ShowPlugins;
6+
use App\Models\Plugin;
7+
use Illuminate\Foundation\Testing\RefreshDatabase;
8+
use Laravel\Pennant\Feature;
9+
use Tests\TestCase;
10+
11+
class PluginShowMobileVersionTest extends TestCase
12+
{
13+
use RefreshDatabase;
14+
15+
protected function setUp(): void
16+
{
17+
parent::setUp();
18+
19+
Feature::define(ShowPlugins::class, true);
20+
}
21+
22+
public function test_plugin_show_displays_mobile_min_version(): void
23+
{
24+
$plugin = Plugin::factory()->approved()->create([
25+
'mobile_min_version' => '^3.0.0',
26+
]);
27+
28+
$this->get(route('plugins.show', $plugin->routeParams()))
29+
->assertStatus(200)
30+
->assertSee('NativePHP Mobile')
31+
->assertSee('^3.0.0');
32+
}
33+
34+
public function test_plugin_show_displays_dash_when_mobile_min_version_is_null(): void
35+
{
36+
$plugin = Plugin::factory()->approved()->create([
37+
'mobile_min_version' => null,
38+
]);
39+
40+
$this->get(route('plugins.show', $plugin->routeParams()))
41+
->assertStatus(200)
42+
->assertSee('NativePHP Mobile');
43+
}
44+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
namespace Tests\Feature;
4+
5+
use App\Models\Plugin;
6+
use App\Services\PluginSyncService;
7+
use Illuminate\Foundation\Testing\RefreshDatabase;
8+
use Illuminate\Support\Facades\Http;
9+
use Tests\TestCase;
10+
11+
class PluginSyncServiceTest extends TestCase
12+
{
13+
use RefreshDatabase;
14+
15+
public function test_sync_extracts_mobile_min_version_from_composer_data(): void
16+
{
17+
$composerJson = json_encode([
18+
'name' => 'acme/test-plugin',
19+
'require' => [
20+
'nativephp/mobile' => '^3.0.0',
21+
],
22+
]);
23+
24+
Http::fake([
25+
'api.github.com/repos/acme/test-plugin/contents/composer.json' => Http::response([
26+
'content' => base64_encode($composerJson),
27+
]),
28+
'api.github.com/repos/acme/test-plugin/contents/nativephp.json' => Http::response([], 404),
29+
'raw.githubusercontent.com/*' => Http::response('', 404),
30+
'api.github.com/repos/acme/test-plugin/releases/latest' => Http::response([], 404),
31+
'api.github.com/repos/acme/test-plugin/tags*' => Http::response([]),
32+
'api.github.com/repos/acme/test-plugin/contents/LICENSE*' => Http::response([], 404),
33+
]);
34+
35+
$plugin = Plugin::factory()->create([
36+
'name' => 'acme/test-plugin',
37+
'repository_url' => 'https://github.com/acme/test-plugin',
38+
'mobile_min_version' => null,
39+
]);
40+
41+
$service = new PluginSyncService;
42+
$result = $service->sync($plugin);
43+
44+
$this->assertTrue($result);
45+
$this->assertEquals('^3.0.0', $plugin->fresh()->mobile_min_version);
46+
}
47+
48+
public function test_sync_sets_mobile_min_version_to_null_when_not_in_composer_data(): void
49+
{
50+
$composerJson = json_encode([
51+
'name' => 'acme/test-plugin',
52+
'require' => [
53+
'php' => '^8.2',
54+
],
55+
]);
56+
57+
Http::fake([
58+
'api.github.com/repos/acme/test-plugin/contents/composer.json' => Http::response([
59+
'content' => base64_encode($composerJson),
60+
]),
61+
'api.github.com/repos/acme/test-plugin/contents/nativephp.json' => Http::response([], 404),
62+
'raw.githubusercontent.com/*' => Http::response('', 404),
63+
'api.github.com/repos/acme/test-plugin/releases/latest' => Http::response([], 404),
64+
'api.github.com/repos/acme/test-plugin/tags*' => Http::response([]),
65+
'api.github.com/repos/acme/test-plugin/contents/LICENSE*' => Http::response([], 404),
66+
]);
67+
68+
$plugin = Plugin::factory()->create([
69+
'name' => 'acme/test-plugin',
70+
'repository_url' => 'https://github.com/acme/test-plugin',
71+
'mobile_min_version' => '^2.0.0',
72+
]);
73+
74+
$service = new PluginSyncService;
75+
$result = $service->sync($plugin);
76+
77+
$this->assertTrue($result);
78+
$this->assertNull($plugin->fresh()->mobile_min_version);
79+
}
80+
}

0 commit comments

Comments
 (0)