events and hooks
This commit is contained in:
+4
-19
@@ -7,7 +7,7 @@ return [
|
|||||||
"database" => env('LUCENT_DB_CONNECTION', env('DB_CONNECTION', "sqlite")),
|
"database" => env('LUCENT_DB_CONNECTION', env('DB_CONNECTION', "sqlite")),
|
||||||
"name" => env("LUCENT_NAME", "Stoic"),
|
"name" => env("LUCENT_NAME", "Stoic"),
|
||||||
"url" => env("LUCENT_URL", env('APP_URL')),
|
"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
|
* Make available laravel artisan commands for admin users
|
||||||
* example:
|
* example:
|
||||||
@@ -18,22 +18,7 @@ return [
|
|||||||
*
|
*
|
||||||
* */
|
* */
|
||||||
"commands" => [],
|
"commands" => [],
|
||||||
"canInvite" => ["admin"],
|
"can_invite" => ["admin"],
|
||||||
"canBuild" => ["admin"],
|
"can_run_commands" => ["admin"],
|
||||||
"systemUserId" => "",
|
"system_user_id" => ""
|
||||||
"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
|
|
||||||
]
|
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ readonly class AuthService
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (app()->runningInConsole()) {
|
if (app()->runningInConsole()) {
|
||||||
return config("lucent.systemUserId");
|
return config("lucent.system_user_id");
|
||||||
} elseif(request()->segment(1) !== "lucent") {
|
} elseif(request()->segment(1) !== "lucent") {
|
||||||
return config("lucent.systemUserId");
|
return config("lucent.system_user_id");
|
||||||
} else {
|
} else {
|
||||||
return $this->session->get("user.id");
|
return $this->session->get("user.id");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ final class Channel
|
|||||||
public string $lucentUrl;
|
public string $lucentUrl;
|
||||||
public string $filesUrl;
|
public string $filesUrl;
|
||||||
public array $disks;
|
public array $disks;
|
||||||
public string $previewTargetUrl;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection<Schema> $schemas
|
* @param Collection<Schema> $schemas
|
||||||
@@ -31,7 +30,7 @@ final class Channel
|
|||||||
$this->lucentUrl = $url . "/lucent";
|
$this->lucentUrl = $url . "/lucent";
|
||||||
$this->filesUrl = $this->makeFilesUrl();
|
$this->filesUrl = $this->makeFilesUrl();
|
||||||
$this->disks = $this->getDisksFromSchemas();
|
$this->disks = $this->getDisksFromSchemas();
|
||||||
$this->previewTargetUrl = $url . "/" . $previewTarget;
|
$this->previewTarget = $url . "/" . $previewTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
namespace Lucent\Channel;
|
namespace Lucent\Channel;
|
||||||
|
|
||||||
|
|
||||||
|
use DirectoryIterator;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Intervention\Image\Drivers\Imagick\Encoders\WebpEncoder;
|
||||||
use Lucent\Channel\Data\UserCommand;
|
use Lucent\Channel\Data\UserCommand;
|
||||||
use Lucent\Primitive\Collection;
|
use Lucent\Primitive\Collection;
|
||||||
use Lucent\Schema\Schema;
|
use Lucent\Schema\Schema;
|
||||||
@@ -38,7 +41,7 @@ final class ChannelService
|
|||||||
$channel = new Channel(
|
$channel = new Channel(
|
||||||
name: config("lucent.name") ?? "",
|
name: config("lucent.name") ?? "",
|
||||||
url: rtrim(config("lucent.url") ?? "", "/"),
|
url: rtrim(config("lucent.url") ?? "", "/"),
|
||||||
previewTarget: rtrim(config("lucent.previewTarget") ?? "", "/"),
|
previewTarget: rtrim(config("lucent.preview_target") ?? "", "/"),
|
||||||
commands: Collection::make($userCommands),
|
commands: Collection::make($userCommands),
|
||||||
schemas: $schemasCollection,
|
schemas: $schemasCollection,
|
||||||
imageFilters: config("lucent.imageFilters") ?? [],
|
imageFilters: config("lucent.imageFilters") ?? [],
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ class CompileSchemas extends Command
|
|||||||
$carry,
|
$carry,
|
||||||
$schema->read,
|
$schema->read,
|
||||||
$schema->write,
|
$schema->write,
|
||||||
config("lucent.canInvite") ?? [],
|
config("lucent.can_invite") ?? [],
|
||||||
config("lucent.canBuild") ?? [],
|
config("lucent.can_run_commands") ?? [],
|
||||||
), []);
|
), []);
|
||||||
|
|
||||||
$json = [
|
$json = [
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Hook;
|
||||||
|
|
||||||
|
class HookService
|
||||||
|
{
|
||||||
|
protected array $hooks = [];
|
||||||
|
|
||||||
|
public function execute(string $name, mixed $params): mixed
|
||||||
|
{
|
||||||
|
if (empty($this->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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
namespace Lucent;
|
namespace Lucent;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Application;
|
||||||
use Illuminate\Routing\Router;
|
use Illuminate\Routing\Router;
|
||||||
use Illuminate\Support\Facades\Blade;
|
use Illuminate\Support\Facades\Blade;
|
||||||
|
use Illuminate\Support\Facades\Event;
|
||||||
use Illuminate\Support\Facades\View;
|
use Illuminate\Support\Facades\View;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Intervention\Image\Drivers\Imagick\Driver;
|
use Intervention\Image\Drivers\Imagick\Driver;
|
||||||
@@ -20,9 +22,14 @@ use Lucent\Commands\Setup;
|
|||||||
use Lucent\Commands\SetupDatabase;
|
use Lucent\Commands\SetupDatabase;
|
||||||
use Lucent\Commands\UpgradeFiles122;
|
use Lucent\Commands\UpgradeFiles122;
|
||||||
use Lucent\File\FileService;
|
use Lucent\File\FileService;
|
||||||
|
use Lucent\Hook\HookService;
|
||||||
use Lucent\Query\DatabaseGraph\DatabaseGraph;
|
use Lucent\Query\DatabaseGraph\DatabaseGraph;
|
||||||
use Lucent\Query\DatabaseGraph\PgsqlDatabaseGraph;
|
use Lucent\Query\DatabaseGraph\PgsqlDatabaseGraph;
|
||||||
use Lucent\Query\DatabaseGraph\SqliteDatabaseGraph;
|
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
|
class LucentServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
@@ -31,16 +38,20 @@ class LucentServiceProvider extends ServiceProvider
|
|||||||
*/
|
*/
|
||||||
public function register(): void
|
public function register(): void
|
||||||
{
|
{
|
||||||
$this->app->singleton(ChannelService::class, function () {
|
$this->app->singleton(ChannelService::class, function (Application $application) {
|
||||||
return ChannelService::fromConfig();
|
return ChannelService::fromConfig();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$this->app->singleton(HookService::class, function (Application $application) {
|
||||||
|
return new HookService;
|
||||||
|
});
|
||||||
|
|
||||||
$this->app->bind(ImageManager::class, function () {
|
$this->app->bind(ImageManager::class, function () {
|
||||||
return new ImageManager(Driver::class);
|
return new ImageManager(Driver::class);
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->mergeConfigFrom(
|
$this->mergeConfigFrom(
|
||||||
__DIR__.'/../config/lucent.php',
|
__DIR__ . '/../config/lucent.php',
|
||||||
'lucent'
|
'lucent'
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -59,6 +70,11 @@ class LucentServiceProvider extends ServiceProvider
|
|||||||
*/
|
*/
|
||||||
public function boot(Router $router): void
|
public function boot(Router $router): void
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$manifestPath = public_path('vendor/lucent/dist/manifest.json');
|
$manifestPath = public_path('vendor/lucent/dist/manifest.json');
|
||||||
$manifest = null;
|
$manifest = null;
|
||||||
if (file_exists($manifestPath)) {
|
if (file_exists($manifestPath)) {
|
||||||
@@ -72,6 +88,7 @@ class LucentServiceProvider extends ServiceProvider
|
|||||||
$this->loadRoutesFrom(__DIR__ . '/Http/web.php');
|
$this->loadRoutesFrom(__DIR__ . '/Http/web.php');
|
||||||
$this->loadRoutesFrom(__DIR__ . '/Http/api.php');
|
$this->loadRoutesFrom(__DIR__ . '/Http/api.php');
|
||||||
|
|
||||||
|
|
||||||
if ($this->app->runningInConsole()) {
|
if ($this->app->runningInConsole()) {
|
||||||
$this->commands([
|
$this->commands([
|
||||||
Setup::class,
|
Setup::class,
|
||||||
@@ -93,11 +110,15 @@ class LucentServiceProvider extends ServiceProvider
|
|||||||
|
|
||||||
$this->publishes([
|
$this->publishes([
|
||||||
__DIR__ . '/../config/lucent.php' => config_path('lucent.php'),
|
__DIR__ . '/../config/lucent.php' => config_path('lucent.php'),
|
||||||
],"lucent-config");
|
], "lucent-config");
|
||||||
|
|
||||||
$this->publishes([
|
$this->publishes([
|
||||||
__DIR__ . '/../front/dist' => public_path('vendor/lucent/dist'),
|
__DIR__ . '/../front/dist' => public_path('vendor/lucent/dist'),
|
||||||
__DIR__ . '/../front/public' => public_path('vendor/lucent/public'),
|
__DIR__ . '/../front/public' => public_path('vendor/lucent/public'),
|
||||||
], 'lucent');
|
], 'lucent');
|
||||||
|
|
||||||
|
|
||||||
|
Event::listen(RecordCreated::class,CreateRevision::class);
|
||||||
|
Event::listen(RecordUpdated::class,CreateRevision::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Record\Event;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Events\Dispatchable;
|
||||||
|
use Lucent\Edge\Edge;
|
||||||
|
use Lucent\Record\Record;
|
||||||
|
|
||||||
|
class RecordCreated
|
||||||
|
{
|
||||||
|
use Dispatchable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Record $record
|
||||||
|
* @param Edge[] $edges
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
public Record $record,
|
||||||
|
public array $edges,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,14 +3,20 @@
|
|||||||
namespace Lucent\Record\Event;
|
namespace Lucent\Record\Event;
|
||||||
|
|
||||||
use Illuminate\Foundation\Events\Dispatchable;
|
use Illuminate\Foundation\Events\Dispatchable;
|
||||||
|
use Lucent\Edge\Edge;
|
||||||
use Lucent\Record\Record;
|
use Lucent\Record\Record;
|
||||||
|
|
||||||
class RecordUpdated
|
class RecordUpdated
|
||||||
{
|
{
|
||||||
use Dispatchable;
|
use Dispatchable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Record $record
|
||||||
|
* @param Edge[] $edges
|
||||||
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public Record $record,
|
public Record $record,
|
||||||
|
public array $edges,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ class RecordRepo
|
|||||||
array $ids,
|
array $ids,
|
||||||
): void
|
): void
|
||||||
{
|
{
|
||||||
|
|
||||||
Database::make()->table("records")->whereIn("id", $ids)->delete();
|
Database::make()->table("records")->whereIn("id", $ids)->delete();
|
||||||
Database::make()->table("edges")->whereIn("source", $ids)->delete();
|
Database::make()->table("edges")->whereIn("source", $ids)->delete();
|
||||||
Database::make()->table("edges")->whereIn("target", $ids)->delete();
|
Database::make()->table("edges")->whereIn("target", $ids)->delete();
|
||||||
|
|||||||
@@ -9,9 +9,12 @@ use Lucent\Channel\ChannelService;
|
|||||||
use Lucent\Edge\Edge;
|
use Lucent\Edge\Edge;
|
||||||
use Lucent\Edge\EdgeService;
|
use Lucent\Edge\EdgeService;
|
||||||
use Lucent\File\FileService;
|
use Lucent\File\FileService;
|
||||||
|
use Lucent\Hook\HookService;
|
||||||
use Lucent\Id\Id;
|
use Lucent\Id\Id;
|
||||||
use Lucent\LucentException;
|
use Lucent\LucentException;
|
||||||
use Lucent\Query\Query;
|
use Lucent\Query\Query;
|
||||||
|
use Lucent\Record\Event\RecordCreated;
|
||||||
|
use Lucent\Record\Event\RecordUpdated;
|
||||||
use Lucent\Record\InputData\EdgeInputData;
|
use Lucent\Record\InputData\EdgeInputData;
|
||||||
use Lucent\Record\InputData\RecordInputData;
|
use Lucent\Record\InputData\RecordInputData;
|
||||||
use Lucent\Revision\RevisionService;
|
use Lucent\Revision\RevisionService;
|
||||||
@@ -34,6 +37,7 @@ readonly class RecordService
|
|||||||
private RecordRepo $recordRepo,
|
private RecordRepo $recordRepo,
|
||||||
private EdgeService $edgeService,
|
private EdgeService $edgeService,
|
||||||
private FileService $fileService,
|
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->inputFormatter->fill($data->schemaName, new RecordData($data->data));
|
||||||
|
$formattedData = $this->hookService->execute("beforeCreate", $formattedData);
|
||||||
$newRecordId = empty($data->id) ? Id::new() : $data->id;
|
$newRecordId = empty($data->id) ? Id::new() : $data->id;
|
||||||
|
|
||||||
$record = new Record(
|
$record = new Record(
|
||||||
@@ -127,8 +132,8 @@ readonly class RecordService
|
|||||||
}
|
}
|
||||||
|
|
||||||
RecordRepo::create($record);
|
RecordRepo::create($record);
|
||||||
$newEdges = $this->edgeService->createManyForRecord($record->id, $edges);
|
$newEdges = $this->edgeService->createManyForRecord($record->id, $edges);
|
||||||
$this->revisionService->create($record, $newEdges);
|
RecordCreated::dispatch($record, $newEdges);
|
||||||
return $record->id;
|
return $record->id;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -149,6 +154,7 @@ readonly class RecordService
|
|||||||
throw new LucentException("Record id is missing");
|
throw new LucentException("Record id is missing");
|
||||||
}
|
}
|
||||||
$formattedData = $this->inputFormatter->fill($record->schema, new RecordData($data));
|
$formattedData = $this->inputFormatter->fill($record->schema, new RecordData($data));
|
||||||
|
$formattedData = $this->hookService->execute("beforeSave", $formattedData);
|
||||||
|
|
||||||
if ($status === Status::PUBLISHED) {
|
if ($status === Status::PUBLISHED) {
|
||||||
$errors = $this->recordValidator->check($record->schema, $formattedData);
|
$errors = $this->recordValidator->check($record->schema, $formattedData);
|
||||||
@@ -168,8 +174,7 @@ readonly class RecordService
|
|||||||
|
|
||||||
RecordRepo::update($newRecord);
|
RecordRepo::update($newRecord);
|
||||||
$newEdges = $this->edgeService->findForSource($record->id);
|
$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);
|
RecordRepo::update($newRecord);
|
||||||
$newEdges = $this->edgeService->replaceManyForRecord($record->id, $edges );
|
$newEdges = $this->edgeService->replaceManyForRecord($record->id, $edges);
|
||||||
$this->revisionService->create($newRecord, $newEdges);
|
RecordUpdated::dispatch($newRecord, $newEdges);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,18 +2,22 @@
|
|||||||
|
|
||||||
namespace Lucent\Revision\Listener;
|
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
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user