diff --git a/config/lucent.php b/config/lucent.php index ce3964b..4177327 100644 --- a/config/lucent.php +++ b/config/lucent.php @@ -7,7 +7,7 @@ return [ "database" => env('LUCENT_DB_CONNECTION', env('DB_CONNECTION', "sqlite")), "name" => env("LUCENT_NAME", "Stoic"), "url" => env("LUCENT_URL", env('APP_URL')), - "previewTarget" => env("LUCENT_PREVIEW_TARGET", "previewTarget"), + "preview_target" => env("LUCENT_PREVIEW_TARGET", "previewTarget"), /* * Make available laravel artisan commands for admin users * example: @@ -18,22 +18,7 @@ return [ * * */ "commands" => [], - "canInvite" => ["admin"], - "canBuild" => ["admin"], - "systemUserId" => "", - "schemaFields" => [ - \Lucent\Schema\Ui\Checkbox::class, - \Lucent\Schema\Ui\Color::class, - \Lucent\Schema\Ui\Date::class, - \Lucent\Schema\Ui\Datetime::class, - \Lucent\Schema\Ui\File::class, - \Lucent\Schema\Ui\Json::class, - \Lucent\Schema\Ui\Markdown::class, - \Lucent\Schema\Ui\Number::class, - \Lucent\Schema\Ui\Reference::class, - \Lucent\Schema\Ui\Rich::class, - \Lucent\Schema\Ui\Slug::class, - \Lucent\Schema\Ui\Text::class, - \Lucent\Schema\Ui\Textarea::class - ] + "can_invite" => ["admin"], + "can_run_commands" => ["admin"], + "system_user_id" => "" ]; diff --git a/src/Account/AuthService.php b/src/Account/AuthService.php index 0098832..765b317 100644 --- a/src/Account/AuthService.php +++ b/src/Account/AuthService.php @@ -27,9 +27,9 @@ readonly class AuthService { if (app()->runningInConsole()) { - return config("lucent.systemUserId"); + return config("lucent.system_user_id"); } elseif(request()->segment(1) !== "lucent") { - return config("lucent.systemUserId"); + return config("lucent.system_user_id"); } else { return $this->session->get("user.id"); } diff --git a/src/Channel/Channel.php b/src/Channel/Channel.php index 21dff29..41f07b3 100644 --- a/src/Channel/Channel.php +++ b/src/Channel/Channel.php @@ -12,7 +12,6 @@ final class Channel public string $lucentUrl; public string $filesUrl; public array $disks; - public string $previewTargetUrl; /** * @param Collection $schemas @@ -31,7 +30,7 @@ final class Channel $this->lucentUrl = $url . "/lucent"; $this->filesUrl = $this->makeFilesUrl(); $this->disks = $this->getDisksFromSchemas(); - $this->previewTargetUrl = $url . "/" . $previewTarget; + $this->previewTarget = $url . "/" . $previewTarget; } diff --git a/src/Channel/ChannelService.php b/src/Channel/ChannelService.php index 75fa258..0f16dbf 100644 --- a/src/Channel/ChannelService.php +++ b/src/Channel/ChannelService.php @@ -3,6 +3,9 @@ namespace Lucent\Channel; +use DirectoryIterator; +use Illuminate\Support\Str; +use Intervention\Image\Drivers\Imagick\Encoders\WebpEncoder; use Lucent\Channel\Data\UserCommand; use Lucent\Primitive\Collection; use Lucent\Schema\Schema; @@ -38,7 +41,7 @@ final class ChannelService $channel = new Channel( name: config("lucent.name") ?? "", url: rtrim(config("lucent.url") ?? "", "/"), - previewTarget: rtrim(config("lucent.previewTarget") ?? "", "/"), + previewTarget: rtrim(config("lucent.preview_target") ?? "", "/"), commands: Collection::make($userCommands), schemas: $schemasCollection, imageFilters: config("lucent.imageFilters") ?? [], diff --git a/src/Commands/CompileSchemas.php b/src/Commands/CompileSchemas.php index ccf33a1..daf7ee1 100644 --- a/src/Commands/CompileSchemas.php +++ b/src/Commands/CompileSchemas.php @@ -33,8 +33,8 @@ class CompileSchemas extends Command $carry, $schema->read, $schema->write, - config("lucent.canInvite") ?? [], - config("lucent.canBuild") ?? [], + config("lucent.can_invite") ?? [], + config("lucent.can_run_commands") ?? [], ), []); $json = [ diff --git a/src/Hook/HookService.php b/src/Hook/HookService.php new file mode 100644 index 0000000..49f4e93 --- /dev/null +++ b/src/Hook/HookService.php @@ -0,0 +1,26 @@ +hooks[$name])) { + return $params; + } + + return array_reduce($this->hooks[$name], fn($result, $hook) => $hook($result), $params); + } + + public function register(string $name, callable $callback, int $priority = 0): void + { + while (isset($this->hooks[$name][$priority])) { + $priority = $priority + 1; + } + $this->hooks[$name][$priority] = $callback; + ksort($this->hooks[$name]); + } +} \ No newline at end of file diff --git a/src/LucentServiceProvider.php b/src/LucentServiceProvider.php index f1279a0..bedca59 100644 --- a/src/LucentServiceProvider.php +++ b/src/LucentServiceProvider.php @@ -2,8 +2,10 @@ namespace Lucent; +use Illuminate\Foundation\Application; use Illuminate\Routing\Router; use Illuminate\Support\Facades\Blade; +use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\View; use Illuminate\Support\ServiceProvider; use Intervention\Image\Drivers\Imagick\Driver; @@ -20,9 +22,14 @@ use Lucent\Commands\Setup; use Lucent\Commands\SetupDatabase; use Lucent\Commands\UpgradeFiles122; use Lucent\File\FileService; +use Lucent\Hook\HookService; use Lucent\Query\DatabaseGraph\DatabaseGraph; use Lucent\Query\DatabaseGraph\PgsqlDatabaseGraph; use Lucent\Query\DatabaseGraph\SqliteDatabaseGraph; +use Lucent\Record\Event\RecordCreated; +use Lucent\Record\Event\RecordUpdated; +use Lucent\Record\Record; +use Lucent\Revision\Listener\CreateRevision; class LucentServiceProvider extends ServiceProvider { @@ -31,16 +38,20 @@ class LucentServiceProvider extends ServiceProvider */ public function register(): void { - $this->app->singleton(ChannelService::class, function () { + $this->app->singleton(ChannelService::class, function (Application $application) { return ChannelService::fromConfig(); }); + $this->app->singleton(HookService::class, function (Application $application) { + return new HookService; + }); + $this->app->bind(ImageManager::class, function () { return new ImageManager(Driver::class); }); $this->mergeConfigFrom( - __DIR__.'/../config/lucent.php', + __DIR__ . '/../config/lucent.php', 'lucent' ); @@ -59,6 +70,11 @@ class LucentServiceProvider extends ServiceProvider */ public function boot(Router $router): void { + + + + + $manifestPath = public_path('vendor/lucent/dist/manifest.json'); $manifest = null; if (file_exists($manifestPath)) { @@ -72,6 +88,7 @@ class LucentServiceProvider extends ServiceProvider $this->loadRoutesFrom(__DIR__ . '/Http/web.php'); $this->loadRoutesFrom(__DIR__ . '/Http/api.php'); + if ($this->app->runningInConsole()) { $this->commands([ Setup::class, @@ -93,11 +110,15 @@ class LucentServiceProvider extends ServiceProvider $this->publishes([ __DIR__ . '/../config/lucent.php' => config_path('lucent.php'), - ],"lucent-config"); + ], "lucent-config"); $this->publishes([ __DIR__ . '/../front/dist' => public_path('vendor/lucent/dist'), __DIR__ . '/../front/public' => public_path('vendor/lucent/public'), ], 'lucent'); + + + Event::listen(RecordCreated::class,CreateRevision::class); + Event::listen(RecordUpdated::class,CreateRevision::class); } } diff --git a/src/Record/Event/RecordCreated.php b/src/Record/Event/RecordCreated.php new file mode 100644 index 0000000..b6601c0 --- /dev/null +++ b/src/Record/Event/RecordCreated.php @@ -0,0 +1,23 @@ +table("records")->whereIn("id", $ids)->delete(); Database::make()->table("edges")->whereIn("source", $ids)->delete(); Database::make()->table("edges")->whereIn("target", $ids)->delete(); diff --git a/src/Record/RecordService.php b/src/Record/RecordService.php index dc0a2e2..183e6b0 100644 --- a/src/Record/RecordService.php +++ b/src/Record/RecordService.php @@ -9,9 +9,12 @@ use Lucent\Channel\ChannelService; use Lucent\Edge\Edge; use Lucent\Edge\EdgeService; use Lucent\File\FileService; +use Lucent\Hook\HookService; use Lucent\Id\Id; use Lucent\LucentException; use Lucent\Query\Query; +use Lucent\Record\Event\RecordCreated; +use Lucent\Record\Event\RecordUpdated; use Lucent\Record\InputData\EdgeInputData; use Lucent\Record\InputData\RecordInputData; use Lucent\Revision\RevisionService; @@ -34,6 +37,7 @@ readonly class RecordService private RecordRepo $recordRepo, private EdgeService $edgeService, private FileService $fileService, + private HookService $hookService, ) { } @@ -108,6 +112,7 @@ readonly class RecordService { $formattedData = $this->inputFormatter->fill($data->schemaName, new RecordData($data->data)); + $formattedData = $this->hookService->execute("beforeCreate", $formattedData); $newRecordId = empty($data->id) ? Id::new() : $data->id; $record = new Record( @@ -127,8 +132,8 @@ readonly class RecordService } RecordRepo::create($record); - $newEdges = $this->edgeService->createManyForRecord($record->id, $edges); - $this->revisionService->create($record, $newEdges); + $newEdges = $this->edgeService->createManyForRecord($record->id, $edges); + RecordCreated::dispatch($record, $newEdges); return $record->id; } @@ -149,6 +154,7 @@ readonly class RecordService throw new LucentException("Record id is missing"); } $formattedData = $this->inputFormatter->fill($record->schema, new RecordData($data)); + $formattedData = $this->hookService->execute("beforeSave", $formattedData); if ($status === Status::PUBLISHED) { $errors = $this->recordValidator->check($record->schema, $formattedData); @@ -168,8 +174,7 @@ readonly class RecordService RecordRepo::update($newRecord); $newEdges = $this->edgeService->findForSource($record->id); - $this->revisionService->create($newRecord, $newEdges); - + RecordUpdated::dispatch($newRecord, $newEdges); } /** @@ -207,8 +212,8 @@ readonly class RecordService ); RecordRepo::update($newRecord); - $newEdges = $this->edgeService->replaceManyForRecord($record->id, $edges ); - $this->revisionService->create($newRecord, $newEdges); + $newEdges = $this->edgeService->replaceManyForRecord($record->id, $edges); + RecordUpdated::dispatch($newRecord, $newEdges); } diff --git a/src/Revision/Listener/CreateRevision.php b/src/Revision/Listener/CreateRevision.php index 3393d77..a96eecc 100644 --- a/src/Revision/Listener/CreateRevision.php +++ b/src/Revision/Listener/CreateRevision.php @@ -2,18 +2,22 @@ namespace Lucent\Revision\Listener; -use Lucent\Edge\Event\EdgesUpdated; +use Lucent\Record\Event\RecordCreated; +use Lucent\Record\Event\RecordUpdated; +use Lucent\Revision\RevisionService; class CreateRevision { - public function __construct() + public function __construct( + private RevisionService $revisionService + ) { } - public function handle(EdgesUpdated $event): void + public function handle(RecordCreated|RecordUpdated $event): void { - + $this->revisionService->create($event->record, $event->edges); } } \ No newline at end of file