-
-
Notifications
You must be signed in to change notification settings - Fork 257
Add basic api for plugins #2146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 5 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
9d4b9bc
add basic plugins api
Boy132 5bc65db
add import endpoint
Boy132 e4efbbe
rename requests
Boy132 a58173d
add endpoints for import via url, enable and disable
Boy132 6fd4ae5
add more information to plugin transformer
Boy132 f630439
small fixes
Boy132 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
203 changes: 203 additions & 0 deletions
203
app/Http/Controllers/Api/Application/Plugins/PluginController.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,203 @@ | ||
| <?php | ||
|
|
||
| namespace App\Http\Controllers\Api\Application\Plugins; | ||
|
|
||
| use App\Enums\PluginStatus; | ||
| use App\Exceptions\PanelException; | ||
| use App\Http\Controllers\Api\Application\ApplicationApiController; | ||
| use App\Http\Requests\Api\Application\Plugins\ImportFilePluginRequest; | ||
| use App\Http\Requests\Api\Application\Plugins\ReadPluginRequest; | ||
| use App\Http\Requests\Api\Application\Plugins\UninstallPluginRequest; | ||
| use App\Http\Requests\Api\Application\Plugins\WritePluginRequest; | ||
| use App\Models\Plugin; | ||
| use App\Services\Helpers\PluginService; | ||
| use App\Transformers\Api\Application\PluginTransformer; | ||
| use Exception; | ||
| use Illuminate\Http\Response; | ||
| use Spatie\QueryBuilder\QueryBuilder; | ||
|
|
||
| class PluginController extends ApplicationApiController | ||
| { | ||
| /** | ||
| * PluginController constructor. | ||
| */ | ||
| public function __construct(private readonly PluginService $pluginService) | ||
| { | ||
| parent::__construct(); | ||
| } | ||
|
|
||
| /** | ||
| * List plugins | ||
| * | ||
| * Return all plugins on the Panel. | ||
| * | ||
| * @return array<array-key, mixed> | ||
| */ | ||
| public function index(ReadPluginRequest $request): array | ||
| { | ||
| $plugins = QueryBuilder::for(Plugin::class) | ||
| ->allowedFilters(['id', 'name', 'author', 'category']) | ||
| ->allowedSorts(['id', 'name', 'author', 'category']) | ||
| ->paginate($request->query('per_page') ?? 10); | ||
|
|
||
| return $this->fractal->collection($plugins) | ||
| ->transformWith($this->getTransformer(PluginTransformer::class)) | ||
| ->toArray(); | ||
| } | ||
|
|
||
| /** | ||
| * View plugin | ||
| * | ||
| * Return a single plugin. | ||
| * | ||
| * @return array<array-key, mixed> | ||
| */ | ||
| public function view(ReadPluginRequest $request, Plugin $plugin): array | ||
| { | ||
| return $this->fractal->item($plugin) | ||
| ->transformWith($this->getTransformer(PluginTransformer::class)) | ||
| ->toArray(); | ||
| } | ||
|
|
||
| /** | ||
| * Import plugin (file) | ||
| * | ||
| * Imports a new plugin file. | ||
| * | ||
| * @throws Exception | ||
| */ | ||
| public function importFile(WritePluginRequest $request): Response | ||
| { | ||
| if (!$request->hasFile('plugin')) { | ||
| throw new PanelException("No 'plugin' file in request"); | ||
| } | ||
|
|
||
| $this->pluginService->downloadPluginFromFile($request->file('plugin')); | ||
|
|
||
| return new Response('', Response::HTTP_CREATED); | ||
| } | ||
|
|
||
| /** | ||
| * Import plugin (url) | ||
| * | ||
| * Imports a new plugin from an url. | ||
| * | ||
| * @throws Exception | ||
| */ | ||
| public function importUrl(ImportFilePluginRequest $request): Response | ||
| { | ||
| $this->pluginService->downloadPluginFromUrl($request->string('url')); | ||
|
|
||
| return new Response('', Response::HTTP_CREATED); | ||
| } | ||
|
|
||
| /** | ||
| * Install plugin | ||
| * | ||
| * Installs and enables a plugin. | ||
| * | ||
| * @return array<array-key, mixed> | ||
| * | ||
| * @throws Exception | ||
| */ | ||
| public function install(WritePluginRequest $request, Plugin $plugin): array | ||
| { | ||
| if ($plugin->status !== PluginStatus::NotInstalled) { | ||
| throw new PanelException('Plugin is already installed'); | ||
| } | ||
|
|
||
| $this->pluginService->installPlugin($plugin); | ||
|
|
||
| return $this->fractal->item($plugin) | ||
| ->transformWith($this->getTransformer(PluginTransformer::class)) | ||
| ->toArray(); | ||
| } | ||
Boy132 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /** | ||
| * Update plugin | ||
| * | ||
| * Downloads and installs an update for a plugin. Will throw if no update is available. | ||
| * | ||
| * @return array<array-key, mixed> | ||
| * | ||
| * @throws Exception | ||
| */ | ||
| public function update(WritePluginRequest $request, Plugin $plugin): array | ||
| { | ||
| if (!$plugin->isUpdateAvailable()) { | ||
| throw new PanelException("Plugin doesn't need updating"); | ||
| } | ||
|
|
||
| $this->pluginService->updatePlugin($plugin); | ||
|
|
||
| return $this->fractal->item($plugin) | ||
| ->transformWith($this->getTransformer(PluginTransformer::class)) | ||
| ->toArray(); | ||
| } | ||
|
|
||
| /** | ||
| * Uninstall plugin | ||
| * | ||
| * Uninstalls a plugin. Optionally it will delete the plugin folder too. | ||
| * | ||
| * @return array<array-key, mixed> | ||
| * | ||
| * @throws Exception | ||
| */ | ||
| public function uninstall(UninstallPluginRequest $request, Plugin $plugin): array | ||
| { | ||
| if ($plugin->status === PluginStatus::NotInstalled) { | ||
| throw new PanelException('Plugin is not installed'); | ||
| } | ||
|
|
||
| $this->pluginService->uninstallPlugin($plugin, $request->boolean('delete')); | ||
|
|
||
| return $this->fractal->item($plugin) | ||
| ->transformWith($this->getTransformer(PluginTransformer::class)) | ||
| ->toArray(); | ||
| } | ||
|
|
||
| /** | ||
| * Enable plugin | ||
| * | ||
| * Enables a plugin. | ||
| * | ||
| * @return array<array-key, mixed> | ||
| * | ||
| * @throws Exception | ||
| */ | ||
| public function enable(WritePluginRequest $request, Plugin $plugin): array | ||
| { | ||
| if (!$plugin->canEnable()) { | ||
| throw new PanelException("Plugin can't be enabled"); | ||
| } | ||
|
|
||
| $this->pluginService->enablePlugin($plugin); | ||
|
|
||
| return $this->fractal->item($plugin) | ||
| ->transformWith($this->getTransformer(PluginTransformer::class)) | ||
| ->toArray(); | ||
| } | ||
|
|
||
| /** | ||
| * Disable plugin | ||
| * | ||
| * Disables a plugin. | ||
| * | ||
| * @return array<array-key, mixed> | ||
| * | ||
| * @throws Exception | ||
| */ | ||
| public function disable(WritePluginRequest $request, Plugin $plugin): array | ||
| { | ||
| if (!$plugin->canDisable()) { | ||
| throw new PanelException("Plugin can't be disabled"); | ||
| } | ||
|
|
||
| $this->pluginService->disablePlugin($plugin); | ||
|
|
||
| return $this->fractal->item($plugin) | ||
| ->transformWith($this->getTransformer(PluginTransformer::class)) | ||
| ->toArray(); | ||
| } | ||
| } | ||
13 changes: 13 additions & 0 deletions
13
app/Http/Requests/Api/Application/Plugins/ImportFilePluginRequest.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| <?php | ||
|
|
||
| namespace App\Http\Requests\Api\Application\Plugins; | ||
|
|
||
| class ImportFilePluginRequest extends WritePluginRequest | ||
| { | ||
| public function rules(): array | ||
| { | ||
| return [ | ||
| 'url' => 'required|string', | ||
| ]; | ||
| } | ||
| } |
14 changes: 14 additions & 0 deletions
14
app/Http/Requests/Api/Application/Plugins/ReadPluginRequest.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| <?php | ||
|
|
||
| namespace App\Http\Requests\Api\Application\Plugins; | ||
|
|
||
| use App\Http\Requests\Api\Application\ApplicationApiRequest; | ||
| use App\Models\Plugin; | ||
| use App\Services\Acl\Api\AdminAcl; | ||
|
|
||
| class ReadPluginRequest extends ApplicationApiRequest | ||
| { | ||
| protected ?string $resource = Plugin::RESOURCE_NAME; | ||
|
|
||
| protected int $permission = AdminAcl::READ; | ||
| } |
17 changes: 17 additions & 0 deletions
17
app/Http/Requests/Api/Application/Plugins/UninstallPluginRequest.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| <?php | ||
|
|
||
| namespace App\Http\Requests\Api\Application\Plugins; | ||
|
|
||
| class UninstallPluginRequest extends WritePluginRequest | ||
| { | ||
| /** | ||
| * @param array<array-key, string|string[]>|null $rules | ||
| * @return array<array-key, string|string[]> | ||
| */ | ||
| public function rules(?array $rules = null): array | ||
| { | ||
| return [ | ||
| 'delete' => 'boolean', | ||
| ]; | ||
| } | ||
| } |
14 changes: 14 additions & 0 deletions
14
app/Http/Requests/Api/Application/Plugins/WritePluginRequest.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| <?php | ||
|
|
||
| namespace App\Http\Requests\Api\Application\Plugins; | ||
|
|
||
| use App\Http\Requests\Api\Application\ApplicationApiRequest; | ||
| use App\Models\Plugin; | ||
| use App\Services\Acl\Api\AdminAcl; | ||
|
|
||
| class WritePluginRequest extends ApplicationApiRequest | ||
| { | ||
| protected ?string $resource = Plugin::RESOURCE_NAME; | ||
|
|
||
| protected int $permission = AdminAcl::WRITE; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| <?php | ||
|
|
||
| namespace App\Transformers\Api\Application; | ||
|
|
||
| use App\Models\Plugin; | ||
|
|
||
| class PluginTransformer extends BaseTransformer | ||
| { | ||
| /** | ||
| * Return the resource name for the JSONAPI output. | ||
| */ | ||
| public function getResourceName(): string | ||
| { | ||
| return Plugin::RESOURCE_NAME; | ||
| } | ||
|
|
||
| /** | ||
| * @param Plugin $model | ||
| */ | ||
| public function transform($model): array | ||
| { | ||
| return [ | ||
| 'id' => $model->id, | ||
| 'name' => $model->name, | ||
| 'author' => $model->author, | ||
| 'version' => $model->version, | ||
| 'description' => $model->description, | ||
| 'category' => $model->category, | ||
| 'url' => $model->url, | ||
| 'update_url' => $model->update_url, | ||
| 'namespace' => $model->namespace, | ||
| 'class' => $model->class, | ||
| 'panels' => $model->panels ? explode(',', $model->panels) : null, | ||
| 'panel_version' => $model->panel_version, | ||
| 'composer_packages' => json_decode($model->composer_packages, true, 512, JSON_THROW_ON_ERROR), | ||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 'meta' => [ | ||
| 'status' => $model->status, | ||
| 'status_message' => $model->status_message, | ||
| 'load_order' => $model->load_order, | ||
| 'is_compatible' => $model->isCompatible(), | ||
| 'update_available' => $model->isUpdateAvailable(), | ||
| 'can_enable' => $model->canEnable(), | ||
| 'can_disable' => $model->canDisable(), | ||
| ], | ||
| ]; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.