mirror of
https://github.com/pelican-dev/panel.git
synced 2026-07-16 05:53:54 +03:00
Implement Webhooks (#548)
* feat: First Webhook PoC draft * feat: Dispatch Webhooks PoC * fix: typo in webhook configuration scope * Update 2024_04_21_162552_create_webhooks_table.php Co-authored-by: Lance Pioch <lancepioch@gmail.com> * Update 2024_04_21_162552_create_webhooks_table.php Co-authored-by: Lance Pioch <lancepioch@gmail.com> * Update 2024_04_21_162544_create_webhook_configurations_table.php Co-authored-by: Lance Pioch <lancepioch@gmail.com> * Update 2024_04_21_162544_create_webhook_configurations_table.php Co-authored-by: Lance Pioch <lancepioch@gmail.com> * Update DispatchWebhooks.php Co-authored-by: Lance Pioch <lancepioch@gmail.com> * Update DispatchWebhooksJob.php Co-authored-by: Lance Pioch <lancepioch@gmail.com> * Update DispatchWebhookForConfiguration.php Co-authored-by: Lance Pioch <lancepioch@gmail.com> * Update DispatchWebhookForConfiguration.php Co-authored-by: Lance Pioch <lancepioch@gmail.com> * Update DispatchWebhookForConfiguration.php Co-authored-by: Lance Pioch <lancepioch@gmail.com> * Update DispatchWebhooksJob.php Co-authored-by: Lance Pioch <lancepioch@gmail.com> * Update DispatchWebhooksJob.php Co-authored-by: Lance Pioch <lancepioch@gmail.com> * Update DispatchWebhooksJob.php Co-authored-by: Lance Pioch <lancepioch@gmail.com> * chore: Implement Webhook Event Discovery * we got a test working for webhooks * WIP * Something is working! * More tests * clean up the tests now that they are passing * WIP * Don't use model specific events * WIP * WIP * WIP * WIP * WIP * Do it sync * Reset these * Don't need restored event type * Deleted some unused jobs * Find custom Events * Remove observers * Add custom event test * Run Pint * Add caching * Don't cache every single event * Fix tests * Run Pint * Phpstan fixes * Pint fix * Test fixes * Middleware unit test fix * Pint fixes * Remove index not working for older dbs * Use facade instead --------- Co-authored-by: Pascale Beier <mail@pascalebeier.de> Co-authored-by: Lance Pioch <lancepioch@gmail.com> Co-authored-by: Vehikl <go@vehikl.com>
This commit is contained in:
120
app/Models/WebhookConfiguration.php
Normal file
120
app/Models/WebhookConfiguration.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class WebhookConfiguration extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'endpoint',
|
||||
'description',
|
||||
'events',
|
||||
];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'events' => 'json',
|
||||
];
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
self::saved(static function (self $webhookConfiguration): void {
|
||||
$changedEvents = collect([
|
||||
...((array) $webhookConfiguration->events),
|
||||
...$webhookConfiguration->getOriginal('events', '[]'),
|
||||
])->unique();
|
||||
|
||||
$changedEvents->each(function (string $event) {
|
||||
cache()->forever("webhooks.$event", WebhookConfiguration::query()->whereJsonContains('events', $event)->get());
|
||||
});
|
||||
|
||||
cache()->forever('watchedWebhooks', WebhookConfiguration::pluck('events')->flatten()->unique()->values()->all());
|
||||
});
|
||||
}
|
||||
|
||||
public function webhooks(): HasMany
|
||||
{
|
||||
return $this->hasMany(Webhook::class);
|
||||
}
|
||||
|
||||
public static function allPossibleEvents(): array
|
||||
{
|
||||
return static::discoverCustomEvents() + static::allModelEvents();
|
||||
}
|
||||
|
||||
public static function filamentCheckboxList(): array
|
||||
{
|
||||
$list = [];
|
||||
$events = static::allPossibleEvents();
|
||||
foreach ($events as $event) {
|
||||
$list[$event] = static::transformClassName($event);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
public static function transformClassName(string $event): string
|
||||
{
|
||||
return str($event)
|
||||
->after('eloquent.')
|
||||
->replace('App\\Models\\', '')
|
||||
->replace('App\\Events\\', 'event: ')
|
||||
->toString();
|
||||
}
|
||||
|
||||
public static function allModelEvents(): array
|
||||
{
|
||||
$eventTypes = ['created', 'updated', 'deleted'];
|
||||
$models = static::discoverModels();
|
||||
|
||||
$events = [];
|
||||
foreach ($models as $model) {
|
||||
foreach ($eventTypes as $eventType) {
|
||||
$events[] = "eloquent.$eventType: $model";
|
||||
}
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
public static function discoverModels(): array
|
||||
{
|
||||
$namespace = 'App\\Models\\';
|
||||
$directory = app_path('Models');
|
||||
|
||||
$models = [];
|
||||
foreach (File::allFiles($directory) as $file) {
|
||||
$models[] = $namespace . str($file->getFilename())
|
||||
->replace([DIRECTORY_SEPARATOR, '.php'], ['\\', '']);
|
||||
}
|
||||
|
||||
return $models;
|
||||
}
|
||||
|
||||
public static function discoverCustomEvents(): array
|
||||
{
|
||||
$directory = app_path('Events');
|
||||
|
||||
$events = [];
|
||||
foreach (File::allFiles($directory) as $file) {
|
||||
$namespace = str($file->getPath())
|
||||
->after(base_path())
|
||||
->replace(DIRECTORY_SEPARATOR, '\\')
|
||||
->replace('\\app\\', 'App\\')
|
||||
->toString();
|
||||
|
||||
$events[] = $namespace . '\\' . str($file->getFilename())
|
||||
->replace([DIRECTORY_SEPARATOR, '.php'], ['\\', '']);
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user