diff --git a/front/js/svelte/Channel.svelte b/front/js/svelte/Channel.svelte
index fa0216b..0d55838 100644
--- a/front/js/svelte/Channel.svelte
+++ b/front/js/svelte/Channel.svelte
@@ -3,7 +3,7 @@
import RecordNotFound from "./records/NotFound.svelte";
import RecordEdit from "./records/Edit.svelte";
import ContentIndex from "./content/Index.svelte";
- import {setContext} from "svelte";
+ import { setContext } from "svelte";
import Navbar from "./layout/Navbar.svelte";
import HomeIndex from "./home/Index.svelte";
import BuildReport from "./build/Report.svelte";
@@ -28,24 +28,21 @@
export let axios;
export let readableSchemas;
-
setContext("axios", axios);
setContext("channel", channel);
- setContext("readableSchemas", channel.schemas.filter((s) => readableSchemas.includes(s.name)));
+ setContext(
+ "readableSchemas",
+ channel.schemas.filter((s) => readableSchemas.includes(s.name)),
+ );
setContext("user", user);
-
-
-
-
-
diff --git a/front/js/svelte/home/Index.svelte b/front/js/svelte/home/Index.svelte
index f781144..ec445ff 100644
--- a/front/js/svelte/home/Index.svelte
+++ b/front/js/svelte/home/Index.svelte
@@ -1,7 +1,6 @@
-
{#if records.length > 0}
-
- {#each records as record (record.id)}
-
-
-
- {/each}
+ {#each records as record (record.id)}
+
+
+
+ {/each}
-
{/if}
-
diff --git a/front/js/svelte/layout/Header.svelte b/front/js/svelte/layout/Header.svelte
index 04ec6c0..8513fc1 100644
--- a/front/js/svelte/layout/Header.svelte
+++ b/front/js/svelte/layout/Header.svelte
@@ -1,25 +1,25 @@
-
-
+
-
diff --git a/front/js/svelte/setup/Step.svelte b/front/js/svelte/setup/Step.svelte
index 955fb7e..606f3f9 100644
--- a/front/js/svelte/setup/Step.svelte
+++ b/front/js/svelte/setup/Step.svelte
@@ -1,11 +1,9 @@
-
{#if step.status === "success"}
@@ -17,26 +15,24 @@
{step.name}
- Instuctions
+ Instructions
{step.instructions}
-
-
\ No newline at end of file
+
diff --git a/src/Account/AccountService.php b/src/Account/AccountService.php
index 82fae53..908bc5d 100644
--- a/src/Account/AccountService.php
+++ b/src/Account/AccountService.php
@@ -7,15 +7,11 @@ use Lucent\Primitive\Collection;
readonly class AccountService
{
-
public function __construct(
- private AuthService $authService,
+ private AuthService $authService,
private ChannelService $channelService,
- private UserRepo $userRepo,
- )
- {
-
- }
+ private UserRepo $userRepo,
+ ) {}
/**
* @return Collection
@@ -25,13 +21,11 @@ readonly class AccountService
return $this->userRepo->all();
}
-
public function countUsers(): int
{
return $this->userRepo->count();
}
-
/**
* @return Collection
*/
@@ -54,6 +48,4 @@ readonly class AccountService
$roles = $this->authService->currentUserRoles();
return $this->channelService->schemasWritableByRoles($roles);
}
-
-
}
diff --git a/src/Account/AuthService.php b/src/Account/AuthService.php
index 0098832..f3a604d 100644
--- a/src/Account/AuthService.php
+++ b/src/Account/AuthService.php
@@ -2,235 +2,52 @@
namespace Lucent\Account;
-use Carbon\Carbon;
-use Illuminate\Contracts\Session\Session;
-use Illuminate\Support\Facades\Mail;
-use Illuminate\Support\Str;
-use Lucent\Channel\ChannelService;
use Lucent\LucentException;
-use Lucent\Mail\LoginMail;
-readonly class AuthService
+interface AuthService
{
+ public function currentUserId(): ?string;
- public function __construct(
- private ChannelService $channelService,
- private UserRepo $userRepo,
- public Session $session,
- )
- {
+ public function currentUserRoles(): array;
+ public function getCurrentUser(): User;
- }
-
-
- public function currentUserId(): ?string
- {
-
- if (app()->runningInConsole()) {
- return config("lucent.systemUserId");
- } elseif(request()->segment(1) !== "lucent") {
- return config("lucent.systemUserId");
- } else {
- return $this->session->get("user.id");
- }
-
- }
-
- public
- function currentUserRoles(): array
- {
- return $this->session->get("user.roles") ?? [];
- }
-
- public
- function isLoggedIn(): bool
- {
- return !empty($this->currentUserId());
- }
+ public function isLoggedIn(): bool;
/**
* @throws LucentException
*/
- public
- function login(string $email, string $token): void
- {
+ public function login(string $email, string $token): void;
- $user = $this->userRepo->findByEmail(new Email($email));
+ public function refreshSession();
- if ($user->isEmpty()) {
- throw new LucentException("Your account was not found");
- }
-
- if ($user->get()->isRemoved()) {
- throw new LucentException("Your account is not active");
- }
-
- if ($user->get()->mailToken !== $token) {
- throw new LucentException("Token has expired or is invalid");
- }
-
- if (Carbon::parse($user->get()->loggedInAt)->lte(Carbon::now()->subHours(1))) {
- throw new LucentException("Token has expired.");
- }
-
- $newUser = $user->get();
- $newUser->updatedAt = Carbon::now()->toJson();
- $newUser->mailToken = null;
- $this->userRepo->update($newUser);
- $this->session->put(["user" => $user->get()->safe()]);
- }
-
- public
- function refreshSession()
- {
-
-
- $user = $this->userRepo->findById($this->currentUserId());
-
- if ($user->isEmpty()) {
- throw new LucentException("Your account was not found");
- }
-
- if ($user->get()->isRemoved()) {
- throw new LucentException("Your account is not active");
- }
-
- $newUser = $user->get();
- $this->session->put(["user" => $user->get()->safe()]);
- }
-
-
- public
- function create(string $name, string $email, array $roles): User
- {
- $user = new User(
- id: (string)Str::uuid(),
- name: new Name($name),
- email: new Email($email),
- roles: $this->validateRoles($roles),
- createdAt: Carbon::now()->toJson(),
- updatedAt: Carbon::now()->toJson(),
- loggedInAt: Carbon::now()->toJson(),
- mailToken: Token::new(32),
- );
-
- $this->userRepo->insert($user);
- return $user;
- }
-
-
-
- public function sendLoginEmail(string $email): void
- {
- $emailAddress = (new Email($email));
- $user = $this->userRepo->findByEmail($emailAddress);
-
- if ($user->isEmpty()) {
- return;
- }
-
- if ($user->get()->isRemoved()) {
- return;
- }
-
- $newToken = $this->userRepo->updateLoginToken($user->get()->id);
-
- Mail::to($email)->send(
- new LoginMail(
- $email,
- $newToken,
- $this->channelService->channel->lucentUrl
- )
- );
- }
+ public function create(string $name, string $email, array $roles): User;
+ public function sendLoginEmail(string $email): void;
/**
* @throws LucentException
*/
- public
- function changeRoles(string $userId, array $roles): void
- {
- $user = $this->userRepo->findById($userId);
-
- if ($user->isEmpty()) {
- throw new LucentException("User not found");
- }
-
- $newUser = $user->get();
- $newUser->roles = $this->validateRoles($roles);
- $newUser->updatedAt = Carbon::now()->toJson();
- $this->userRepo->update($newUser);
- }
+ public function changeRoles(string $userId, array $roles): void;
/**
* @throws LucentException
*/
- public
- function updateName(string $name): void
- {
- $name = (new Name($name));
- $this->userRepo->updateName($this->currentUserId(), $name);
- $user = $this->userRepo->findById($this->currentUserId());
- $this->session->put(["user" => $user->get()->safe()]);
- }
+ public function updateName(string $name): void;
/**
* @throws LucentException
*/
- public
- function updateEmail(string $email): void
- {
- $email = (new Email($email));
- $user = $this->userRepo->findByEmail($email);
- if ($user->isDefined()) {
- throw new LucentException("Email already assigned to user");
- }
-
- $this->userRepo->updateEmail($this->currentUserId(), $email);
- $user = $this->userRepo->findById($this->currentUserId());
- $this->session->put(["user" => $user->get()->safe()]);
- }
-
+ public function updateEmail(string $email): void;
/**
* @throws LucentException
*/
- public
- function invite(
- string $name,
- string $email,
- array $roles
- ): User
- {
- $user = $this->create($name, $email, $roles);
- $this->sendLoginEmail($user->email);
- return $user;
- }
+ public function invite(string $name, string $email, array $roles): User;
/**
* @throws LucentException
*/
- public
- function registerAdmin(
- string $name,
- string $email
- ): User
- {
- $user = $this->invite($name, $email, ["admin"]);
- $this->sendLoginEmail($user->email);
- return $user;
- }
-
- public
- function validateRoles(array $roles): array
- {
- return collect($roles)
- ->filter(fn(string $role) => in_array($role, $this->channelService->channel->roles))
- ->unique()
- ->values()
- ->toArray();
- }
-
+ public function registerAdmin(string $name, string $email): User;
+ public function validateRoles(array $roles): array;
}
diff --git a/src/Account/AuthServiceLucent.php b/src/Account/AuthServiceLucent.php
new file mode 100644
index 0000000..1a30c68
--- /dev/null
+++ b/src/Account/AuthServiceLucent.php
@@ -0,0 +1,224 @@
+runningInConsole()) {
+ return config("lucent.systemUserId");
+ } elseif (request()->segment(1) !== "lucent") {
+ return config("lucent.systemUserId");
+ }
+ return $this->session->get("user.id");
+ }
+
+ public function currentUserRoles(): array
+ {
+ return $this->session->get("user.roles") ?? [];
+ }
+
+ public function getCurrentUser(): User
+ {
+ return new User(
+ id: $this->session->get("user.id"),
+ name: new Name($this->session->get("user.name")),
+ email: new Email($this->session->get("user.email")),
+ roles: $this->session->get("user.roles"),
+ createdAt: $this->session->get("user.createdAt"),
+ updatedAt: $this->session->get("user.updatedAt"),
+ loggedInAt: null,
+ mailToken: null,
+ );
+ }
+
+ public function isLoggedIn(): bool
+ {
+ return !empty($this->currentUserId());
+ }
+
+ /**
+ * @throws LucentException
+ */
+ public function login(string $email, string $token): void
+ {
+ $user = $this->userRepo->findByEmail(new Email($email));
+
+ if ($user->isEmpty()) {
+ throw new LucentException("Your account was not found");
+ }
+
+ if ($user->get()->isRemoved()) {
+ throw new LucentException("Your account is not active");
+ }
+
+ if ($user->get()->mailToken !== $token) {
+ throw new LucentException("Token has expired or is invalid");
+ }
+
+ if (
+ Carbon::parse($user->get()->loggedInAt)->lte(
+ Carbon::now()->subHours(1),
+ )
+ ) {
+ throw new LucentException("Token has expired.");
+ }
+
+ $newUser = $user->get();
+ $newUser->updatedAt = Carbon::now()->toJson();
+ $newUser->mailToken = null;
+ $this->userRepo->update($newUser);
+ $this->session->put(["user" => $user->get()->safe()]);
+ }
+
+ public function refreshSession()
+ {
+ $user = $this->userRepo->findById($this->currentUserId());
+
+ if ($user->isEmpty()) {
+ throw new LucentException("Your account was not found");
+ }
+
+ if ($user->get()->isRemoved()) {
+ throw new LucentException("Your account is not active");
+ }
+
+ $newUser = $user->get();
+ $this->session->put(["user" => $user->get()->safe()]);
+ }
+
+ public function create(string $name, string $email, array $roles): User
+ {
+ $user = new User(
+ id: (string) Str::uuid(),
+ name: new Name($name),
+ email: new Email($email),
+ roles: $this->validateRoles($roles),
+ createdAt: Carbon::now()->toJson(),
+ updatedAt: Carbon::now()->toJson(),
+ loggedInAt: Carbon::now()->toJson(),
+ mailToken: Token::new(32),
+ );
+
+ $this->userRepo->insert($user);
+ return $user;
+ }
+
+ public function sendLoginEmail(string $email): void
+ {
+ $emailAddress = new Email($email);
+ $user = $this->userRepo->findByEmail($emailAddress);
+
+ if ($user->isEmpty()) {
+ return;
+ }
+
+ if ($user->get()->isRemoved()) {
+ return;
+ }
+
+ $newToken = $this->userRepo->updateLoginToken($user->get()->id);
+
+ Mail::to($email)->send(
+ new LoginMail(
+ $email,
+ $newToken,
+ $this->channelService->channel->lucentUrl,
+ ),
+ );
+ }
+
+ /**
+ * @throws LucentException
+ */
+ public function changeRoles(string $userId, array $roles): void
+ {
+ $user = $this->userRepo->findById($userId);
+
+ if ($user->isEmpty()) {
+ throw new LucentException("User not found");
+ }
+
+ $newUser = $user->get();
+ $newUser->roles = $this->validateRoles($roles);
+ $newUser->updatedAt = Carbon::now()->toJson();
+ $this->userRepo->update($newUser);
+ }
+
+ /**
+ * @throws LucentException
+ */
+ public function updateName(string $name): void
+ {
+ $name = new Name($name);
+ $this->userRepo->updateName($this->currentUserId(), $name);
+ $user = $this->userRepo->findById($this->currentUserId());
+ $this->session->put(["user" => $user->get()->safe()]);
+ }
+
+ /**
+ * @throws LucentException
+ */
+ public function updateEmail(string $email): void
+ {
+ $email = new Email($email);
+ $user = $this->userRepo->findByEmail($email);
+ if ($user->isDefined()) {
+ throw new LucentException("Email already assigned to user");
+ }
+
+ $this->userRepo->updateEmail($this->currentUserId(), $email);
+ $user = $this->userRepo->findById($this->currentUserId());
+ $this->session->put(["user" => $user->get()->safe()]);
+ }
+
+ /**
+ * @throws LucentException
+ */
+ public function invite(string $name, string $email, array $roles): User
+ {
+ $user = $this->create($name, $email, $roles);
+ $this->sendLoginEmail($user->email);
+ return $user;
+ }
+
+ /**
+ * @throws LucentException
+ */
+ public function registerAdmin(string $name, string $email): User
+ {
+ $user = $this->invite($name, $email, ["admin"]);
+ $this->sendLoginEmail($user->email);
+ return $user;
+ }
+
+ public function validateRoles(array $roles): array
+ {
+ return collect($roles)
+ ->filter(
+ fn(string $role) => in_array(
+ $role,
+ $this->channelService->channel->roles,
+ ),
+ )
+ ->unique()
+ ->values()
+ ->toArray();
+ }
+}
diff --git a/src/Account/AuthServiceLunar.php b/src/Account/AuthServiceLunar.php
new file mode 100644
index 0000000..5fcf4f8
--- /dev/null
+++ b/src/Account/AuthServiceLunar.php
@@ -0,0 +1,104 @@
+runningInConsole()) {
+ return config("lucent.systemUserId");
+ } elseif (request()->segment(1) !== "lucent") {
+ return config("lucent.systemUserId");
+ }
+ return Filament::auth()->user()->id;
+ }
+ public function getCurrentUser(): User
+ {
+ return new User(
+ id: Filament::auth()->user()->id,
+ name: new Name(
+ Filament::auth()->user()->first_name .
+ " " .
+ Filament::auth()->user()->last_name,
+ ),
+ email: new Email(Filament::auth()->user()->email),
+ roles: [],
+ createdAt: Filament::auth()->user()->created_at,
+ updatedAt: Filament::auth()->user()->updated_at,
+ loggedInAt: null,
+ mailToken: null,
+ );
+ }
+
+ public function currentUserRoles(): array
+ {
+ return [];
+ }
+
+ public function isLoggedIn(): bool
+ {
+ return !empty($this->currentUserId());
+ }
+
+ /**
+ * @throws LucentException
+ */
+ public function login(string $email, string $token): void {}
+
+ public function refreshSession() {}
+
+ public function create(string $name, string $email, array $roles): User {}
+
+ public function sendLoginEmail(string $email): void {}
+
+ /**
+ * @throws LucentException
+ */
+ public function changeRoles(string $userId, array $roles): void {}
+
+ /**
+ * @throws LucentException
+ */
+ public function updateName(string $name): void {}
+
+ /**
+ * @throws LucentException
+ */
+ public function updateEmail(string $email): void {}
+
+ /**
+ * @throws LucentException
+ */
+ public function invite(string $name, string $email, array $roles): User {}
+
+ /**
+ * @throws LucentException
+ */
+ public function registerAdmin(string $name, string $email): User {}
+
+ public function validateRoles(array $roles): array
+ {
+ return collect($roles)
+ ->filter(
+ fn(string $role) => in_array(
+ $role,
+ $this->channelService->channel->roles,
+ ),
+ )
+ ->unique()
+ ->values()
+ ->toArray();
+ }
+}
diff --git a/src/Account/UserRepo.php b/src/Account/UserRepo.php
index 84d638f..3c08a2c 100644
--- a/src/Account/UserRepo.php
+++ b/src/Account/UserRepo.php
@@ -2,111 +2,37 @@
namespace Lucent\Account;
-use Carbon\Carbon;
-use Lucent\Database\Database;
use Lucent\Primitive\Collection;
use PhpOption\Option;
-class UserRepo
+interface UserRepo
{
-
- public function count(): int
- {
- return Database::make()->table("users")->count();
- }
+ public function count(): int;
/**
* @return Collection
*/
- public function all(): Collection
- {
- $usersData = Database::make()->table("users")->get();
+ public function all(): Collection;
- $users = array_map(fn($userData) => $this->fromArray((array)$userData), $usersData->toArray());
- return new Collection($users);
- }
+ public static function insert(User $user): void;
+ public function update(User $user): void;
- public static function insert(User $user): void
- {
- $userData = toArray($user);
- $userData["roles"] = json_encode($userData["roles"]);
- Database::make()->table("users")->insert($userData);
- }
-
- public function update(User $user): void
- {
- $userData = toArray($user);
- $userData["roles"] = json_encode($userData["roles"]);
- Database::make()->table("users")->where("id", $user->id)->update($userData);
- }
-
-
- public function updateLoginToken(string $id): string
- {
- $newToken = Token::new(32);
-
- Database::make()->table("users")
- ->where("id", $id)
- ->update([
- 'loggedInAt' => Carbon::now()->toJson(),
- 'mailToken' => $newToken,
- ]);
-
- return $newToken;
- }
-
+ public function updateLoginToken(string $id): string;
/**
* @return Option
*/
- public function findByEmail(Email $email): Option
- {
- $user = Database::make()->table("users")->where("email", $email->value())->first();
-
- if (empty($user)) {
- return none();
- }
-
- return some($this->fromArray((array)$user));
- }
+ public function findByEmail(Email $email): Option;
/**
* @return Option
*/
- public function findById(string $id): Option
- {
- $user = Database::make()->table("users")->where("id", $id)->first();
+ public function findById(string $id): Option;
- if (empty($user)) {
- return none();
- }
+ public function updateName(string $userId, Name $name): void;
- return some($this->fromArray((array)$user));
- }
+ public function updateEmail(string $userId, Email $email): void;
-
- public function updateName(string $userId, Name $name): void
- {
- Database::make()->table("users")->where("id", $userId)->update(["name" => $name->value]);
- }
-
- public function updateEmail(string $userId, Email $email): void
- {
- Database::make()->table("users")->where("id", $userId)->update(["email" => $email->value()]);
- }
-
- public function fromArray(array $data): User
- {
- return new User(
- id: $data["id"],
- name: new Name($data["name"] ?? ""),
- email: new Email($data["email"]),
- roles: json_decode($data["roles"] ?? "[]", true),
- createdAt: $data["createdAt"],
- updatedAt: $data["updatedAt"],
- loggedInAt: $data["loggedInAt"] ?? null,
- mailToken: $data["mailToken"] ?? null,
- );
- }
+ public function fromArray(array $data): User;
}
diff --git a/src/Account/UserRepoLucent.php b/src/Account/UserRepoLucent.php
new file mode 100644
index 0000000..7f9bdfe
--- /dev/null
+++ b/src/Account/UserRepoLucent.php
@@ -0,0 +1,128 @@
+table($this->tableName)->count();
+ }
+
+ /**
+ * @return Collection
+ */
+ public function all(): Collection
+ {
+ $usersData = Database::make()->table($this->tableName)->get();
+
+ $users = array_map(
+ fn($userData) => $this->fromArray((array) $userData),
+ $usersData->toArray(),
+ );
+ return new Collection($users);
+ }
+
+ public static function insert(User $user): void
+ {
+ $userData = toArray($user);
+ $userData["roles"] = json_encode($userData["roles"]);
+ Database::make()->table($this->tableName)->insert($userData);
+ }
+
+ public function update(User $user): void
+ {
+ $userData = toArray($user);
+ $userData["roles"] = json_encode($userData["roles"]);
+ Database::make()
+ ->table($this->tableName)
+ ->where("id", $user->id)
+ ->update($userData);
+ }
+
+ public function updateLoginToken(string $id): string
+ {
+ $newToken = Token::new(32);
+
+ Database::make()
+ ->table($this->tableName)
+ ->where("id", $id)
+ ->update([
+ "loggedInAt" => Carbon::now()->toJson(),
+ "mailToken" => $newToken,
+ ]);
+
+ return $newToken;
+ }
+
+ /**
+ * @return Option
+ */
+ public function findByEmail(Email $email): Option
+ {
+ $user = Database::make()
+ ->table($this->tableName)
+ ->where("email", $email->value())
+ ->first();
+
+ if (empty($user)) {
+ return none();
+ }
+
+ return some($this->fromArray((array) $user));
+ }
+
+ /**
+ * @return Option
+ */
+ public function findById(string $id): Option
+ {
+ $user = Database::make()
+ ->table($this->tableName)
+ ->where("id", $id)
+ ->first();
+
+ if (empty($user)) {
+ return none();
+ }
+
+ return some($this->fromArray((array) $user));
+ }
+
+ public function updateName(string $userId, Name $name): void
+ {
+ Database::make()
+ ->table($this->tableName)
+ ->where("id", $userId)
+ ->update(["name" => $name->value]);
+ }
+
+ public function updateEmail(string $userId, Email $email): void
+ {
+ Database::make()
+ ->table($this->tableName)
+ ->where("id", $userId)
+ ->update(["email" => $email->value()]);
+ }
+
+ public function fromArray(array $data): User
+ {
+ return new User(
+ id: $data["id"],
+ name: new Name($data["name"] ?? ""),
+ email: new Email($data["email"]),
+ roles: json_decode($data["roles"] ?? "[]", true),
+ createdAt: $data["createdAt"],
+ updatedAt: $data["updatedAt"],
+ loggedInAt: $data["loggedInAt"] ?? null,
+ mailToken: $data["mailToken"] ?? null,
+ );
+ }
+}
diff --git a/src/Account/UserRepoLunar.php b/src/Account/UserRepoLunar.php
new file mode 100644
index 0000000..9b7a787
--- /dev/null
+++ b/src/Account/UserRepoLunar.php
@@ -0,0 +1,130 @@
+table($this->tableName)->count();
+ }
+
+ /**
+ * @return Collection
+ */
+ public function all(): Collection
+ {
+ $usersData = Database::make()->table($this->tableName)->get();
+
+ $users = array_map(
+ fn($userData) => $this->fromArray((array) $userData),
+ $usersData->toArray(),
+ );
+ return new Collection($users);
+ }
+
+ public static function insert(User $user): void
+ {
+ $userData = toArray($user);
+ $userData["roles"] = json_encode($userData["roles"]);
+ Database::make()->table($this->tableName)->insert($userData);
+ }
+
+ public function update(User $user): void
+ {
+ $userData = toArray($user);
+ $userData["roles"] = json_encode($userData["roles"]);
+ Database::make()
+ ->table($this->tableName)
+ ->where("id", $user->id)
+ ->update($userData);
+ }
+
+ public function updateLoginToken(string $id): string
+ {
+ $newToken = Token::new(32);
+
+ Database::make()
+ ->table($this->tableName)
+ ->where("id", $id)
+ ->update([
+ "loggedInAt" => Carbon::now()->toJson(),
+ "mailToken" => $newToken,
+ ]);
+
+ return $newToken;
+ }
+
+ /**
+ * @return Option
+ */
+ public function findByEmail(Email $email): Option
+ {
+ $user = Database::make()
+ ->table($this->tableName)
+ ->where("email", $email->value())
+ ->first();
+
+ if (empty($user)) {
+ return none();
+ }
+
+ return some($this->fromArray((array) $user));
+ }
+
+ /**
+ * @return Option
+ */
+ public function findById(string $id): Option
+ {
+ $user = Database::make()
+ ->table($this->tableName)
+ ->where("id", $id)
+ ->first();
+
+ if (empty($user)) {
+ return none();
+ }
+
+ return some($this->fromArray((array) $user));
+ }
+
+ public function updateName(string $userId, Name $name): void
+ {
+ Database::make()
+ ->table($this->tableName)
+ ->where("id", $userId)
+ ->update(["name" => $name->value]);
+ }
+
+ public function updateEmail(string $userId, Email $email): void
+ {
+ Database::make()
+ ->table($this->tableName)
+ ->where("id", $userId)
+ ->update(["email" => $email->value()]);
+ }
+
+ public function fromArray(array $data): User
+ {
+ return new User(
+ id: $data["id"],
+ name: new Name(
+ $data["first_name"] . " " . $data["last_name"] ?? "",
+ ),
+ email: new Email($data["email"]),
+ roles: [],
+ createdAt: $data["created_at"],
+ updatedAt: $data["updated_at"],
+ loggedInAt: null,
+ mailToken: null,
+ );
+ }
+}
diff --git a/src/Channel/ChannelService.php b/src/Channel/ChannelService.php
index 75fa258..942c834 100644
--- a/src/Channel/ChannelService.php
+++ b/src/Channel/ChannelService.php
@@ -2,7 +2,6 @@
namespace Lucent\Channel;
-
use Lucent\Channel\Data\UserCommand;
use Lucent\Primitive\Collection;
use Lucent\Schema\Schema;
@@ -13,12 +12,7 @@ final class ChannelService
{
public Channel $channel;
- private function __construct(
- public SchemaService $schemaService,
- )
- {
-
- }
+ private function __construct(public SchemaService $schemaService) {}
public static function fromConfig(): ChannelService
{
@@ -28,7 +22,10 @@ final class ChannelService
$schemasArray = json_decode($schemasJson, true);
}
$schemaService = new SchemaService();
- $schemasCollection = (new Collection($schemasArray["schemas"] ?? []))->map([$schemaService, 'fromArray']);
+ $schemasCollection = new Collection($schemasArray["schemas"] ?? []);
+ $schemasCollection = $schemasCollection->map(
+ $schemaService->fromArray(...),
+ );
$userCommands = [];
foreach (config("lucent.commands") ?? [] as $signature => $desc) {
@@ -42,7 +39,7 @@ final class ChannelService
commands: Collection::make($userCommands),
schemas: $schemasCollection,
imageFilters: config("lucent.imageFilters") ?? [],
- roles: $schemasArray["roles"] ?? []
+ roles: $schemasArray["roles"] ?? [],
);
$channelService = new ChannelService($schemaService);
@@ -69,11 +66,32 @@ final class ChannelService
*/
public function schemasReadableByRoles(array $roles): array
{
- $schemasAllRead = $this->channel->schemas->filter(fn(Schema $schema) => empty($schema->read))->values()->pluck("name");
- $schemasCanRead = $this->channel->schemas->filter(fn(Schema $schema) => count(array_intersect($schema->read ?? [], $roles)) > 0)->values()->pluck("name");
- $schemasCanWrite = $this->channel->schemas->filter(fn(Schema $schema) => count(array_intersect($schema->write ?? [], $roles)) > 0)->values()->pluck("name");
- return $schemasAllRead->merge($schemasCanRead)->merge($schemasCanWrite)->unique()->values()->toArray();
-
+ $schemasAllRead = $this->channel->schemas
+ ->filter(fn(Schema $schema) => empty($schema->read))
+ ->values()
+ ->pluck("name");
+ $schemasCanRead = $this->channel->schemas
+ ->filter(
+ fn(Schema $schema) => count(
+ array_intersect($schema->read ?? [], $roles),
+ ) > 0,
+ )
+ ->values()
+ ->pluck("name");
+ $schemasCanWrite = $this->channel->schemas
+ ->filter(
+ fn(Schema $schema) => count(
+ array_intersect($schema->write ?? [], $roles),
+ ) > 0,
+ )
+ ->values()
+ ->pluck("name");
+ return $schemasAllRead
+ ->merge($schemasCanRead)
+ ->merge($schemasCanWrite)
+ ->unique()
+ ->values()
+ ->toArray();
}
/**
@@ -82,9 +100,22 @@ final class ChannelService
*/
public function schemasWritableByRoles(array $roles): array
{
- $schemasAllRead = $this->channel->schemas->filter(fn(Schema $schema) => empty($schema->write ?? []))->values()->pluck("name");
- $schemasCanWrite = $this->channel->schemas->filter(fn(Schema $schema) => count(array_intersect($schema->write ?? [], $roles)) > 0)->values()->pluck("name");
- return $schemasAllRead->merge($schemasCanWrite)->unique()->values()->toArray();
+ $schemasAllRead = $this->channel->schemas
+ ->filter(fn(Schema $schema) => empty($schema->write ?? []))
+ ->values()
+ ->pluck("name");
+ $schemasCanWrite = $this->channel->schemas
+ ->filter(
+ fn(Schema $schema) => count(
+ array_intersect($schema->write ?? [], $roles),
+ ) > 0,
+ )
+ ->values()
+ ->pluck("name");
+ return $schemasAllRead
+ ->merge($schemasCanWrite)
+ ->unique()
+ ->values()
+ ->toArray();
}
-
}
diff --git a/src/Command/CommandRepo.php b/src/Command/CommandRepo.php
index 4e84fd6..fa94be9 100644
--- a/src/Command/CommandRepo.php
+++ b/src/Command/CommandRepo.php
@@ -10,7 +10,7 @@ class CommandRepo
public function findBySignature($signature): ?CommandLogItem
{
- $row = Database::make()->table("command_logs")->where("signature", $signature)->first();
+ $row = Database::make()->table("lucent_command_logs")->where("signature", $signature)->first();
if (empty($row)) {
return null;
}
@@ -22,17 +22,17 @@ class CommandRepo
{
$foundCommandLogItem = $this->findBySignature($commandLogItem->signature);
if (empty($foundCommandLogItem)) {
- Database::make()->table("command_logs")->insert(toArray($commandLogItem));
+ Database::make()->table("lucent_command_logs")->insert(toArray($commandLogItem));
return;
}
- Database::make()->table("command_logs")->where("signature", $commandLogItem->signature)->update(toArray($commandLogItem));
+ Database::make()->table("lucent_command_logs")->where("signature", $commandLogItem->signature)->update(toArray($commandLogItem));
}
public function appendToLogs(string $signature, string $line): void
{
Database::make()->update(
- 'update command_logs set logs = logs || ? where signature = ?',
+ 'update lucent_command_logs set logs = logs || ? where signature = ?',
[$line, $signature]
);
diff --git a/src/Commands/SetupDatabase.php b/src/Commands/SetupDatabase.php
index 8f7bdad..01cb383 100644
--- a/src/Commands/SetupDatabase.php
+++ b/src/Commands/SetupDatabase.php
@@ -4,27 +4,18 @@ namespace Lucent\Commands;
use Illuminate\Console\Command;
use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\DB;
use Lucent\Database\Database;
class SetupDatabase extends Command
{
+ protected $signature = "lucent:setup-db";
+ protected $prefix = "lucent_";
- protected $signature = 'lucent:setup-db';
-
- protected $description = 'Run to setup a new database';
-
+ protected $description = "Run to setup a new database";
public function handle()
{
-
- $dbConnection = config("lucent.database");
- $databasePath = config("database.connections.$dbConnection.database");
-
- if(file_exists($databasePath)){
- $this->error("Database already exists.");
- return 0;
- }
- touch($databasePath);
$this->tableUsers();
$this->tableRecords();
$this->tableRevisions();
@@ -36,79 +27,115 @@ class SetupDatabase extends Command
private function tableUsers(): void
{
- Database::make()->getSchemaBuilder()->create('users', function (Blueprint $table) {
+ $schema = Database::make()->getSchemaBuilder();
+ if ($schema->hasTable($this->prefix . "users")) {
+ return;
+ }
+ $schema->create($this->prefix . "users", function (Blueprint $table) {
$table->uuid("id")->primary();
- $table->string('name')->nullable();
- $table->string('email')->unique();
- $table->jsonb('roles');
- $table->string('createdAt');
- $table->string('updatedAt');
- $table->string('loggedInAt');
- $table->string('mailToken')->nullable();
-
+ $table->string("name")->nullable();
+ $table->string("email")->unique();
+ $table->jsonb("roles");
+ $table->string("createdAt");
+ $table->string("updatedAt");
+ $table->string("loggedInAt");
+ $table->string("mailToken")->nullable();
});
}
private function tableSessions(): void
{
- Database::make()->getSchemaBuilder()->create('sessions', function (Blueprint $table) {
- $table->string('id')->primary();
- $table->foreignId('user_id')->nullable()->index();
- $table->string('ip_address', 45)->nullable();
- $table->text('user_agent')->nullable();
- $table->longText('payload');
- $table->integer('last_activity')->index();
+ $schema = Database::make()->getSchemaBuilder();
+ if ($schema->hasTable($this->prefix . "sessions")) {
+ return;
+ }
+ $schema->create($this->prefix . "sessions", function (
+ Blueprint $table,
+ ) {
+ $table->string("id")->primary();
+ $table->foreignId("user_id")->nullable()->index();
+ $table->string("ip_address", 45)->nullable();
+ $table->text("user_agent")->nullable();
+ $table->longText("payload");
+ $table->integer("last_activity")->index();
});
}
private function tableRecords(): void
{
- Database::make()->getSchemaBuilder()->create('records', function (Blueprint $table) {
- $table->uuid('id')->primary();
- $table->string('schema');
- $table->string('status');
- $table->jsonb('data');
- $table->jsonb('_sys');
- $table->jsonb('_file');
- $table->text('search')->default("");
+ $schema = Database::make()->getSchemaBuilder();
+ if (!$schema->hasTable($this->prefix . "records")) {
+ $schema->create($this->prefix . "records", function (
+ Blueprint $table,
+ ) {
+ $table->uuid("id")->primary();
+ $table->string("schema");
+ $table->string("status");
+ $table->jsonb("data");
+ $table->jsonb("_sys");
+ $table->jsonb("_file");
+ $table->text("search")->default("");
- $table->index(['schema', '_sys->updatedAt', 'status']);
- $table->index('search');
- });
+ // $table->index(["schema", "_sys->updatedAt", "status"]);
- Database::make()->getSchemaBuilder()->create('edges', function (Blueprint $table) {
- $table->uuid('source');
- $table->uuid('target');
- $table->string('sourceSchema');
- $table->string('targetSchema');
- $table->string('field');
- $table->string('rank');
+ $table->index("search");
+ });
- $table->unique(['source', 'target', "field"]);
- });
+ DB::statement(
+ "CREATE INDEX ON " .
+ $this->prefix .
+ 'records (schema, ((_sys->>\'updatedAt\')), status)',
+ );
+ }
+
+ if (!$schema->hasTable($this->prefix . "edges")) {
+ $schema->create($this->prefix . "edges", function (
+ Blueprint $table,
+ ) {
+ $table->uuid("source");
+ $table->uuid("target");
+ $table->string("sourceSchema");
+ $table->string("targetSchema");
+ $table->string("field");
+ $table->string("rank");
+
+ $table->unique(["source", "target", "field"]);
+ });
+ }
}
private function tableRevisions(): void
{
- Database::make()->getSchemaBuilder()->create('revisions', function (Blueprint $table) {
- $table->uuid('id')->primary();
- $table->uuid('recordId');
- $table->string('schema');
- $table->jsonb('data');
- $table->jsonb('_sys');
- $table->jsonb('_file');
- $table->jsonb('_edges');
+ $schema = Database::make()->getSchemaBuilder();
+ if ($schema->hasTable($this->prefix . "revisions")) {
+ return;
+ }
+ $schema->create($this->prefix . "revisions", function (
+ Blueprint $table,
+ ) {
+ $table->uuid("id")->primary();
+ $table->uuid("recordId");
+ $table->string("schema");
+ $table->jsonb("data");
+ $table->jsonb("_sys");
+ $table->jsonb("_file");
+ $table->jsonb("_edges");
});
}
private function tableCommandLogs(): void
{
- Database::make()->getSchemaBuilder()->create('command_logs', function (Blueprint $table) {
- $table->uuid('id')->primary();
- $table->string('signature');
- $table->integer('pid')->nullable();
- $table->text('logs');
+ $schema = Database::make()->getSchemaBuilder();
+ if ($schema->hasTable($this->prefix . "command_logs")) {
+ return;
+ }
+ $schema->create($this->prefix . "command_logs", function (
+ Blueprint $table,
+ ) {
+ $table->uuid("id")->primary();
+ $table->string("signature");
+ $table->integer("pid")->nullable();
+ $table->text("logs");
});
}
-
}
diff --git a/src/Commands/UpgradeFiles122.php b/src/Commands/UpgradeFiles122.php
index 51f4ac4..57d6e93 100644
--- a/src/Commands/UpgradeFiles122.php
+++ b/src/Commands/UpgradeFiles122.php
@@ -17,11 +17,11 @@ class UpgradeFiles122 extends Command
$schema = $this->argument('schema');
$disk = $this->argument('disk');
$db = Database::make();
- $records = $db->table("records")->where("schema", $schema)->get();
+ $records = $db->table("lucent_records")->where("schema", $schema)->get();
foreach ($records as $record) {
$array = json_decode($record->_file, true);
$array["disk"] = $disk;
- $db->table("records")->where("id", $record->id)->update(["_file" => json_encode($array)]);
+ $db->table("lucent_records")->where("id", $record->id)->update(["_file" => json_encode($array)]);
}
}
}
diff --git a/src/Database/Database.php b/src/Database/Database.php
index 125fa81..ae5b4a7 100644
--- a/src/Database/Database.php
+++ b/src/Database/Database.php
@@ -7,11 +7,10 @@ use Illuminate\Support\Facades\DB;
class Database
{
- public static function make(): Connection{
- $dbConnection = config("lucent.database");
+ public static function make(): Connection
+ {
+ // $dbConnection = config("lucent.database");
- return DB::connection($dbConnection);
+ return DB::connection();
}
-
-
-}
\ No newline at end of file
+}
diff --git a/src/Edge/EdgeRepo.php b/src/Edge/EdgeRepo.php
index cfee348..7f2a001 100644
--- a/src/Edge/EdgeRepo.php
+++ b/src/Edge/EdgeRepo.php
@@ -15,7 +15,7 @@ class EdgeRepo
public function insert(Edge $edge): void
{
try {
- Database::make()->table("edges")->insert($edge->toDB());
+ Database::make()->table("lucent_edges")->insert($edge->toDB());
} catch (PDOException $e) {
if ($e->getCode() == 23505) {
throw new LucentException("Edge already exists");
@@ -34,7 +34,7 @@ class EdgeRepo
{
$edgesDB = collect($edges)->map(fn($e) => $e->toDB())->toArray();
try {
- Database::make()->table("edges")->insert($edgesDB);
+ Database::make()->table("lucent_edges")->insert($edgesDB);
} catch (PDOException $e) {
if ($e->getCode() == 23505) {
throw new LucentException("Edge already exists");
@@ -52,8 +52,8 @@ class EdgeRepo
public function replaceForRecord(string $from, array $edges): void
{
$edgesDB = collect($edges)->map(fn($e) => $e->toDB())->toArray();
- Database::make()->table("edges")->where("source", $from)->delete();
- Database::make()->table("edges")->insert($edgesDB);
+ Database::make()->table("lucent_edges")->where("source", $from)->delete();
+ Database::make()->table("lucent_edges")->insert($edgesDB);
}
@@ -62,13 +62,13 @@ class EdgeRepo
*/
public function findAll(): array
{
- $edges = Database::make()->table("edges")->get();
+ $edges = Database::make()->table("lucent_edges")->get();
return $edges->map([$this, 'mapEdge'])->toArray();
}
public function findForSource(string $recordId): array
{
- $edges = Database::make()->table("edges")->where("source", $recordId)->get();
+ $edges = Database::make()->table("lucent_edges")->where("source", $recordId)->get();
return $edges->map([$this, 'mapEdge'])->toArray();
}
@@ -89,7 +89,7 @@ class EdgeRepo
public function remove(Edge $edge): void
{
- Database::make()->table("edges")
+ Database::make()->table("lucent_edges")
->where("source", $edge->source)
->where("target", $edge->target)
->where("sourceSchema", $edge->sourceSchema)
@@ -100,7 +100,7 @@ class EdgeRepo
public function findLastEdgeRank(string $source, string $field): string
{
- $data = Database::make()->table("edges")
+ $data = Database::make()->table("lucent_edges")
->where("source", $source)
->where("field", $field)
->orderBy("rank", "desc")
diff --git a/src/File/FileService.php b/src/File/FileService.php
index 63595af..12580e8 100644
--- a/src/File/FileService.php
+++ b/src/File/FileService.php
@@ -123,7 +123,7 @@ class FileService
private function checkDuplicate(string $schemaName, string $checksum, int $filesize): string
{
- $record = Database::make()->table("records")
+ $record = Database::make()->table("lucent_records")
->where("schema", $schemaName)
->where("_file->checksum", $checksum)
->where("_file->size", $filesize)
diff --git a/src/Http/Controller/AuthController.php b/src/Http/Controller/AuthController.php
index 0de07ab..9e17261 100644
--- a/src/Http/Controller/AuthController.php
+++ b/src/Http/Controller/AuthController.php
@@ -2,7 +2,6 @@
namespace Lucent\Http\Controller;
-use App\Http\Controllers\Controller;
use Illuminate\Contracts\Session\Session;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
@@ -13,44 +12,37 @@ use Lucent\Account\AuthService;
use Lucent\Channel\ChannelService;
use Lucent\LucentException;
use Lucent\Svelte\Svelte;
-use Lucent\Util\Form\FormException;
use Lucent\Util\Form\ResponseFormError;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
-
class AuthController
{
public function __construct(
- private readonly AuthService $authService,
+ private readonly AuthService $authService,
private readonly AccountService $accountService,
private readonly ChannelService $channelService,
- private readonly Session $session,
- private readonly Svelte $svelte,
- )
- {
-
- }
+ private readonly Session $session,
+ private readonly Svelte $svelte,
+ ) {}
public function register(Request $request): View|RedirectResponse
{
if ($this->accountService->countUsers() > 0) {
- return redirect($this->channelService->channel->lucentUrl . "/login");
+ return redirect(
+ $this->channelService->channel->lucentUrl . "/login",
+ );
}
-
return $this->svelte->render(
layout: "account",
view: "register",
title: "Create an account",
-
);
}
-
public function postRegister(Request $request): Response
{
-
if ($this->accountService->countUsers() > 0) {
abort(400);
}
@@ -70,7 +62,9 @@ class AuthController
public function login()
{
if ($this->accountService->countUsers() == 0) {
- return redirect($this->channelService->channel->lucentUrl . "/register");
+ return redirect(
+ $this->channelService->channel->lucentUrl . "/register",
+ );
}
return view("lucent::auth.login");
@@ -89,25 +83,24 @@ class AuthController
"email" => $request->input("email"),
"token" => $request->input("token"),
]);
-
}
public function postVerify(Request $request)
{
try {
- $this->authService->login($request->input("email"), $request->input("token"));
+ $this->authService->login(
+ $request->input("email"),
+ $request->input("token"),
+ );
} catch (LucentException $th) {
return ResponseFormError::fromException($th);
}
return [];
}
-
public function logout(): RedirectResponse
{
$this->session->flush();
return redirect($this->channelService->channel->lucentUrl . "/login");
}
-
-
}
diff --git a/src/Http/Controller/HomeController.php b/src/Http/Controller/HomeController.php
index 049708b..2b9ab75 100644
--- a/src/Http/Controller/HomeController.php
+++ b/src/Http/Controller/HomeController.php
@@ -14,16 +14,13 @@ use function Lucent\Response\ok;
class HomeController extends Controller
{
public function __construct(
- private readonly Svelte $svelte,
+ private readonly Svelte $svelte,
private readonly AccountService $accountService,
- private readonly Query $query,
- )
- {
- }
+ private readonly Query $query,
+ ) {}
public function home(): View
{
-
return $this->svelte->render(
layout: "channel",
view: "homeIndex",
@@ -38,10 +35,13 @@ class HomeController extends Controller
$sort = data_get($urlParams, "sort") ?? "-_sys.updatedAt";
$filter = data_get($urlParams, "filter") ?? [];
- $arguments = array_merge([
- "schema_in" => $this->accountService->currentReadableSchemas(),
- "status_in" => ["draft", "published"]
- ], $filter);
+ $arguments = array_merge(
+ [
+ "schema_in" => $this->accountService->currentReadableSchemas(),
+ "status_in" => ["draft", "published"],
+ ],
+ $filter,
+ );
$limit = 20;
diff --git a/src/Http/Controller/RecordController.php b/src/Http/Controller/RecordController.php
index 7274aab..c6fa399 100644
--- a/src/Http/Controller/RecordController.php
+++ b/src/Http/Controller/RecordController.php
@@ -27,23 +27,26 @@ use function Lucent\Response\ok;
class RecordController extends Controller
{
public function __construct(
- private readonly RecordService $recordService,
- private readonly AccountService $accountService,
- private readonly ChannelService $channelService,
- private readonly Svelte $svelte,
- private readonly Query $query,
- private readonly Manager $recordManager,
+ private readonly RecordService $recordService,
+ private readonly AccountService $accountService,
+ private readonly ChannelService $channelService,
+ private readonly Svelte $svelte,
+ private readonly Query $query,
+ private readonly Manager $recordManager,
private readonly OperatorRegistry $operatorRegistry,
private readonly ViewModel $viewModel,
- )
- {
- }
+ ) {}
public function index(Request $request)
{
$schemaName = $request->route("schemaName");
- if (!in_array($schemaName, $this->accountService->currentReadableSchemas())) {
+ if (
+ !in_array(
+ $schemaName,
+ $this->accountService->currentReadableSchemas(),
+ )
+ ) {
return $this->svelte->render(
layout: "channel",
view: "recordNotFound",
@@ -53,16 +56,18 @@ class RecordController extends Controller
$users = $this->accountService->all();
$schema = $this->channelService->getSchema($schemaName)->get();
+
$urlParams = $request->all();
$sort = data_get($urlParams, "sort") ?? $schema->sortBy;
$filter = data_get($urlParams, "filter") ?? [];
- $arguments = array_merge([
- "schema" => $schema->name,
- "status_in" => "draft,published",
- ], $filter);
-
-
+ $arguments = array_merge(
+ [
+ "schema" => $schema->name,
+ "status_in" => "draft,published",
+ ],
+ $filter,
+ );
$skip = data_get($urlParams, "skip") ?? 0;
$limit = 30;
@@ -81,7 +86,6 @@ class RecordController extends Controller
->parentsDepth(0)
->runWithCount();
-
$records = $graph->getRootRecords()->toArray();
$data = [
@@ -93,45 +97,64 @@ class RecordController extends Controller
"systemFields" => array_values(System::list()),
"operators" => $this->operatorRegistry->all(),
"sortParam" => $sort,
- "sortField" => $schema->fields->merge(array_values(System::list()))->firstWhere(fn($field) => $field->name === $sort || "-" . $field->name === $sort || "data." . $field->name === $sort || "-data." . $field->name === $sort),
+ "sortField" => $schema->fields
+ ->merge(array_values(System::list()))
+ ->firstWhere(
+ fn($field) => $field->name === $sort ||
+ "-" . $field->name === $sort ||
+ "data." . $field->name === $sort ||
+ "-data." . $field->name === $sort,
+ ),
"limit" => $limit,
"skip" => $skip,
"total" => $graph->total ?? 0,
"filter" => $request->input("filter") ?? [],
"inModal" => true,
- "isWritable" => in_array($schemaName, $this->accountService->currentWritableSchemas())
+ "isWritable" => in_array(
+ $schemaName,
+ $this->accountService->currentWritableSchemas(),
+ ),
];
if ($request->ajax()) {
$data["modalUrl"] = $request->fullUrl();
if (str_starts_with(config("lucent.url"), "https")) {
- $data["modalUrl"] = str_replace("http://", "https://", $request->fullUrl());
+ $data["modalUrl"] = str_replace(
+ "http://",
+ "https://",
+ $request->fullUrl(),
+ );
}
return $data;
}
$data["inModal"] = false;
+
return $this->svelte->render(
layout: "channel",
view: "contentIndex",
title: "Records",
- data: $data
+ data: $data,
);
}
public function exportCSV(Request $request)
{
$schemaName = $request->route("schemaName");
- $schema = $this->channelService->channel->schemas->where("name", $schemaName)->first();
+ $schema = $this->channelService->channel->schemas
+ ->where("name", $schemaName)
+ ->first();
$urlParams = $request->all();
$sort = data_get($urlParams, "sort") ?? "-_sys.updatedAt";
$filter = data_get($urlParams, "filter") ?? [];
- $arguments = array_merge([
- "schema" => $schema->name,
- "status_in" => "draft,published",
- ], $filter);
-
+ $arguments = array_merge(
+ [
+ "schema" => $schema->name,
+ "status_in" => "draft,published",
+ ],
+ $filter,
+ );
$records = $this->query
->filter($arguments)
@@ -143,53 +166,75 @@ class RecordController extends Controller
->run()
->tree();
- header('Content-Type: application/csv');
- header('Content-Disposition: attachment; filename="' . $schemaName . '.csv";');
- $handle = fopen('php://output', 'w');
+ header("Content-Type: application/csv");
+ header(
+ 'Content-Disposition: attachment; filename="' .
+ $schemaName .
+ '.csv";',
+ );
+ $handle = fopen("php://output", "w");
$relationColumns = $this->makeCsvRelationColumns($schema);
- $csvRow = ["id", ...array_keys($records[0]->data->toArray()),...$relationColumns];
- fputcsv($handle, $csvRow, ',');
+ $csvRow = [
+ "id",
+ ...array_keys($records[0]->data->toArray()),
+ ...$relationColumns,
+ ];
+ fputcsv($handle, $csvRow, ",");
foreach ($records as $record) {
-
$csvRow = [$record->id, ...$record->data->toArray()];
- $csvRow = array_merge($csvRow,$this->makeCsvRelationColumnValues($schema,$record->_children));
+ $csvRow = array_merge(
+ $csvRow,
+ $this->makeCsvRelationColumnValues($schema, $record->_children),
+ );
$csvRow = array_values($csvRow);
- fputcsv($handle, $csvRow, ',');
+ fputcsv($handle, $csvRow, ",");
}
fclose($handle);
echo $handle;
- exit;
+ exit();
}
- private function makeCsvRelationColumns($schema):array{
- return $schema->fields->filter(fn($f) => get_class($f) === Reference::class)->reduce(function($c,$f){
- $c[] = $f->name." id";
- $c[] = $f->name." name";
- return $c;
- },[]);
+ private function makeCsvRelationColumns($schema): array
+ {
+ return $schema->fields
+ ->filter(fn($f) => get_class($f) === Reference::class)
+ ->reduce(function ($c, $f) {
+ $c[] = $f->name . " id";
+ $c[] = $f->name . " name";
+ return $c;
+ }, []);
}
- private function makeCsvRelationColumnValues($schema, $children):array{
- return $schema->fields->filter(fn($f) => get_class($f) === Reference::class)->reduce(function($c,$f) use($children){
-
- $fieldRecords = data_get($children,$f->name);
- if(empty($fieldRecords)){
- $c[] = "";
- $c[] = "";
- }elseif (count($fieldRecords) === 1){
- $c[] = data_get($fieldRecords,"0.id");
- $c[] = $this->viewModel->getRecordName($fieldRecords[0]);
- }else{
- $c[] = collect($fieldRecords)->pluck("id")->join("::");
- $c[] = collect($fieldRecords)->pluck("data.name")->join("::");
- }
- return $c;
- },[]);
+ private function makeCsvRelationColumnValues($schema, $children): array
+ {
+ return $schema->fields
+ ->filter(fn($f) => get_class($f) === Reference::class)
+ ->reduce(function ($c, $f) use ($children) {
+ $fieldRecords = data_get($children, $f->name);
+ if (empty($fieldRecords)) {
+ $c[] = "";
+ $c[] = "";
+ } elseif (count($fieldRecords) === 1) {
+ $c[] = data_get($fieldRecords, "0.id");
+ $c[] = $this->viewModel->getRecordName($fieldRecords[0]);
+ } else {
+ $c[] = collect($fieldRecords)->pluck("id")->join("::");
+ $c[] = collect($fieldRecords)
+ ->pluck("data.name")
+ ->join("::");
+ }
+ return $c;
+ }, []);
}
public function new(Request $request)
{
- if (!in_array($request->input("schema"), $this->accountService->currentWritableSchemas())) {
+ if (
+ !in_array(
+ $request->input("schema"),
+ $this->accountService->currentWritableSchemas(),
+ )
+ ) {
return $this->svelte->render(
layout: "channel",
view: "recordNotFound",
@@ -197,8 +242,12 @@ class RecordController extends Controller
);
}
- $schema = $this->channelService->channel->schemas->where("name", $request->input("schema"))->first();
- $recordHistory = $this->recordManager->fromSession($request->session())->getRecords();
+ $schema = $this->channelService->channel->schemas
+ ->where("name", $request->input("schema"))
+ ->first();
+ $recordHistory = $this->recordManager
+ ->fromSession($request->session())
+ ->getRecords();
$record = $this->recordService->createEmpty($schema);
$queryRecord = QueryRecord::fromRecord($record);
return $this->svelte->render(
@@ -210,15 +259,22 @@ class RecordController extends Controller
"record" => $queryRecord,
"recordHistory" => $recordHistory,
"isCreateMode" => true,
- "isWritable" => in_array($record->schema, $this->accountService->currentWritableSchemas())
- ]
+ "isWritable" => in_array(
+ $record->schema,
+ $this->accountService->currentWritableSchemas(),
+ ),
+ ],
);
}
-
public function newInline(Request $request)
{
- if (!in_array($request->input("schema"), $this->accountService->currentWritableSchemas())) {
+ if (
+ !in_array(
+ $request->input("schema"),
+ $this->accountService->currentWritableSchemas(),
+ )
+ ) {
return $this->svelte->render(
layout: "channel",
view: "recordNotFound",
@@ -226,7 +282,9 @@ class RecordController extends Controller
);
}
- $schema = $this->channelService->getSchema($request->input("schema"))->get();
+ $schema = $this->channelService
+ ->getSchema($request->input("schema"))
+ ->get();
$record = $this->recordService->createEmpty($schema);
$queryRecord = QueryRecord::fromRecord($record);
@@ -234,7 +292,10 @@ class RecordController extends Controller
"schema" => $schema,
"record" => $queryRecord,
"isCreateMode" => true,
- "isWritable" => in_array($record->schema, $this->accountService->currentWritableSchemas())
+ "isWritable" => in_array(
+ $record->schema,
+ $this->accountService->currentWritableSchemas(),
+ ),
];
}
@@ -262,7 +323,12 @@ class RecordController extends Controller
$record = $graph->records->first();
- if (!in_array($record->schema, $this->accountService->currentReadableSchemas())) {
+ if (
+ !in_array(
+ $record->schema,
+ $this->accountService->currentReadableSchemas(),
+ )
+ ) {
return $this->svelte->render(
layout: "channel",
view: "recordNotFound",
@@ -271,7 +337,10 @@ class RecordController extends Controller
}
$schema = $this->channelService->getSchema($record->schema)->get();
- $recordHistory = $this->recordManager->fromSession($request->session())->push($rid)->getRecords($rid);
+ $recordHistory = $this->recordManager
+ ->fromSession($request->session())
+ ->push($rid)
+ ->getRecords($rid);
return $this->svelte->render(
layout: "channel",
view: "recordEdit",
@@ -282,8 +351,11 @@ class RecordController extends Controller
"record" => toArray($record),
"users" => $this->accountService->all(),
"recordHistory" => $recordHistory,
- "isWritable" => in_array($record->schema, $this->accountService->currentWritableSchemas())
- ]
+ "isWritable" => in_array(
+ $record->schema,
+ $this->accountService->currentWritableSchemas(),
+ ),
+ ],
);
}
@@ -295,19 +367,20 @@ class RecordController extends Controller
if ($request->input("value")) {
if (in_array($request->input("ui"), ["text", "date"])) {
- $arguments["data." . $request->input("field") . "_regex"] = $request->input("value");
+ $arguments[
+ "data." . $request->input("field") . "_regex"
+ ] = $request->input("value");
} elseif ($request->input("ui") == "number") {
- $arguments["data." . $request->input("field") . "_eqnum"] = floatval($request->input("value"));
+ $arguments[
+ "data." . $request->input("field") . "_eqnum"
+ ] = floatval($request->input("value"));
} elseif ($request->input("ui") == "date") {
} elseif ($request->input("ui") == "search") {
$arguments["search_regex"] = $request->input("value");
}
}
- $records = $this->query
- ->filter($arguments)
- ->limit(10)
- ->tree();
+ $records = $this->query->filter($arguments)->limit(10)->tree();
if ($records->isEmpty()) {
return ok([]);
@@ -320,7 +393,6 @@ class RecordController extends Controller
{
$recordId = $request->input("record.id");
try {
-
if ($request->input("isCreateMode")) {
$recordId = $this->recordService->create(
data: new RecordInputData(
@@ -329,15 +401,20 @@ class RecordController extends Controller
$request->input("record.data"),
Status::from($request->input("record.status")),
),
- edges: array_map(EdgeInputData::fromArray(...), $request->input("edges") ?? [])
+ edges: array_map(
+ EdgeInputData::fromArray(...),
+ $request->input("edges") ?? [],
+ ),
);
} else {
-
$this->recordService->updateWithEdges(
id: $request->input("record.id"),
data: $request->input("record.data"),
status: Status::from($request->input("record.status")),
- edges: array_map(EdgeInputData::fromArray(...), $request->input("edges") ?? []),
+ edges: array_map(
+ EdgeInputData::fromArray(...),
+ $request->input("edges") ?? [],
+ ),
);
}
@@ -347,7 +424,6 @@ class RecordController extends Controller
->childrenDepth(1)
->parentsDepth(1)
->run();
-
} catch (ValidatorException $th) {
return fail($th->getValidatorErrors());
} catch (LucentException $th) {
@@ -356,11 +432,9 @@ class RecordController extends Controller
return ok(toArray($newGraph));
}
-
public function clone(Request $request)
{
try {
-
$newRecordId = $this->recordService->clone(
recordId: $request->route("rid"),
);
@@ -374,10 +448,8 @@ class RecordController extends Controller
public function status(Request $request)
{
-
$ids = array_map(fn($rec) => $rec["id"], $request->input("records"));
-
$this->recordService->changeStatusBulk(
status: $request->route("status"),
recordsIds: $ids,
@@ -387,9 +459,12 @@ class RecordController extends Controller
public function emptyTrash(Request $request)
{
-
$this->recordService->emptyTrash($request->route("schemaName"));
- return redirect($this->channelService->channel->lucentUrl . "/content/" . $request->route("schemaName"));
+ return redirect(
+ $this->channelService->channel->lucentUrl .
+ "/content/" .
+ $request->route("schemaName"),
+ );
}
public function delete(Request $request)
@@ -409,11 +484,11 @@ class RecordController extends Controller
try {
$this->recordService->rollback(
recordId: $request->route("rid"),
- version: (int)$request->route("version")
+ version: (int) $request->route("version"),
);
} catch (ValidatorException $th) {
return fail($th->getFirstValidatorError());
- } catch (LucentException|Throwable $th) {
+ } catch (LucentException | Throwable $th) {
return fail($th);
}
return ok();
diff --git a/src/Http/Middleware/AuthMiddleware.php b/src/Http/Middleware/AuthMiddleware.php
index a274b37..8f271e5 100644
--- a/src/Http/Middleware/AuthMiddleware.php
+++ b/src/Http/Middleware/AuthMiddleware.php
@@ -16,21 +16,29 @@ readonly class AuthMiddleware
private AuthService $authService,
private AccountService $accountService,
private ChannelService $channelService,
- private ViewModel $viewModel
- )
- {
- }
+ private ViewModel $viewModel,
+ ) {}
public function handle(Request $request, Closure $next)
{
if (!$this->authService->isLoggedIn()) {
- return redirect($this->channelService->channel->lucentUrl . "/login");
+ return redirect(
+ $this->channelService->channel->lucentUrl . "/login",
+ );
}
$this->authService->refreshSession();
- View::share("channel",$this->channelService->channel);
- View::share("user",session("user"));
- View::share("schemas",$this->channelService->channel->schemas->whereIn("name",$this->accountService->currentReadableSchemas())->values());
- View::share("viewModel",$this->viewModel);
+ View::share("channel", $this->channelService->channel);
+ View::share("user", toArray($this->authService->getCurrentUser()));
+ View::share(
+ "schemas",
+ $this->channelService->channel->schemas
+ ->whereIn(
+ "name",
+ $this->accountService->currentReadableSchemas(),
+ )
+ ->values(),
+ );
+ View::share("viewModel", $this->viewModel);
return $next($request);
}
diff --git a/src/LucentServiceProvider.php b/src/LucentServiceProvider.php
index 61bf101..2fc4d1a 100644
--- a/src/LucentServiceProvider.php
+++ b/src/LucentServiceProvider.php
@@ -7,6 +7,10 @@ use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
use Intervention\Image\ImageManager;
+use Lucent\Account\AuthService;
+use Lucent\Account\AuthServiceLunar;
+use Lucent\Account\UserRepo;
+use Lucent\Account\UserRepoLunar;
use Lucent\Channel\ChannelService;
use Lucent\Commands\CompileSchemas;
use Lucent\Commands\GenerateCollectionSchema;
@@ -17,10 +21,8 @@ use Lucent\Commands\RemoveOrphanEdges;
use Lucent\Commands\SetupDatabase;
use Lucent\Commands\UpgradeFiles122;
use Lucent\File\FileService;
-use Lucent\File\ImageService;
use Lucent\Query\DatabaseGraph\DatabaseGraph;
use Lucent\Query\DatabaseGraph\PgsqlDatabaseGraph;
-use Lucent\Query\DatabaseGraph\SqliteDatabaseGraph;
class LucentServiceProvider extends ServiceProvider
{
@@ -34,21 +36,20 @@ class LucentServiceProvider extends ServiceProvider
});
$this->app->bind(ImageManager::class, function () {
- return new ImageManager(['driver' => 'imagick']);
+ return new ImageManager(["driver" => "imagick"]);
});
-
-
$this->app->bind(DatabaseGraph::class, function () {
- $dbConnection = config("lucent.database");
- return match (config("database.connections.$dbConnection.driver")) {
- "sqlite" => new SqliteDatabaseGraph(),
- "pgsql" => new PgsqlDatabaseGraph(),
- };
+ return new PgsqlDatabaseGraph();
});
+ $this->app->bind(UserRepo::class, function () {
+ return new UserRepoLunar();
+ });
-
+ $this->app->bind(AuthService::class, function ($app) {
+ return $app->make(AuthServiceLunar::class);
+ });
}
/**
@@ -56,20 +57,29 @@ class LucentServiceProvider extends ServiceProvider
*/
public function boot(Router $router): void
{
-
- $manifestPath = public_path('vendor/lucent/dist/manifest.json');
+ $manifestPath = public_path("vendor/lucent/dist/manifest.json");
$manifest = null;
if (file_exists($manifestPath)) {
- $manifest = json_decode(file_get_contents(public_path('vendor/lucent/dist/manifest.json')), true);
+ $manifest = json_decode(
+ file_get_contents(
+ public_path("vendor/lucent/dist/manifest.json"),
+ ),
+ true,
+ );
}
+ $router->aliasMiddleware(
+ "lucent.auth",
+ \Lucent\Http\Middleware\AuthMiddleware::class,
+ );
+ $router->aliasMiddleware(
+ "lucent.guest",
+ \Lucent\Http\Middleware\GuestMiddleware::class,
+ );
- $router->aliasMiddleware('lucent.auth', \Lucent\Http\Middleware\AuthMiddleware::class);
- $router->aliasMiddleware('lucent.guest', \Lucent\Http\Middleware\GuestMiddleware::class);
-
- $this->loadViewsFrom(__DIR__ . '/../front/views', 'lucent');
- $this->loadRoutesFrom(__DIR__ . '/Http/web.php');
- $this->loadRoutesFrom(__DIR__ . '/Http/api.php');
+ $this->loadViewsFrom(__DIR__ . "/../front/views", "lucent");
+ $this->loadRoutesFrom(__DIR__ . "/Http/web.php");
+ $this->loadRoutesFrom(__DIR__ . "/Http/api.php");
if ($this->app->runningInConsole()) {
$this->commands([
@@ -84,19 +94,28 @@ class LucentServiceProvider extends ServiceProvider
]);
}
- View::share('manifest', $manifest);
- View::share('file', app()->make(FileService::class));
- Blade::anonymousComponentPath(__DIR__ . '../front/views/components', "lucent");
-
- $this->publishes([
- __DIR__ . '/Config/main.php' => config_path('lucent.php'),
- ],"lucent-config");
-
- $this->publishes([
- __DIR__ . '/../front/dist' => public_path('vendor/lucent/dist'),
- __DIR__ . '/../front/public' => public_path('vendor/lucent/public'),
- ], 'lucent');
+ View::share("manifest", $manifest);
+ View::share("file", app()->make(FileService::class));
+ Blade::anonymousComponentPath(
+ __DIR__ . "../front/views/components",
+ "lucent",
+ );
+ $this->publishes(
+ [
+ __DIR__ . "/Config/main.php" => config_path("lucent.php"),
+ ],
+ "lucent-config",
+ );
+ $this->publishes(
+ [
+ __DIR__ . "/../front/dist" => public_path("vendor/lucent/dist"),
+ __DIR__ . "/../front/public" => public_path(
+ "vendor/lucent/public",
+ ),
+ ],
+ "lucent",
+ );
}
}
diff --git a/src/Query/DatabaseGraph/PgsqlDatabaseGraph.php b/src/Query/DatabaseGraph/PgsqlDatabaseGraph.php
index 606e1b1..d606201 100644
--- a/src/Query/DatabaseGraph/PgsqlDatabaseGraph.php
+++ b/src/Query/DatabaseGraph/PgsqlDatabaseGraph.php
@@ -14,7 +14,7 @@ class PgsqlDatabaseGraph implements DatabaseGraph
*/
public function getChildren(array $ids, QueryOptions $options): array
{
- $subquery = Database::make()->table('edges AS g')
+ $subquery = Database::make()->table('lucent_edges AS g')
->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth '))
->whereIn('source', $ids);
@@ -24,7 +24,7 @@ class PgsqlDatabaseGraph implements DatabaseGraph
$subquery->limit($options->childrenLimit)
->unionAll(
- Database::make()->table(DB::raw("edges AS g, search_graph AS sg "))
+ Database::make()->table(DB::raw("lucent_edges AS g, search_graph AS sg "))
->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.source = sg.target")
->where("depth", "<", $options->childrenDepth)
@@ -42,12 +42,12 @@ class PgsqlDatabaseGraph implements DatabaseGraph
*/
public function getParents(array $ids, QueryOptions $options): array
{
- $subquery = Database::make()->table('edges AS g')
+ $subquery = Database::make()->table('lucent_edges AS g')
->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth '))
->limit($options->parentsLimit)
->whereIn('g.target', $ids)
->unionAll(
- Database::make()->table(DB::raw("edges AS g, search_graph AS sg "))
+ Database::make()->table(DB::raw("lucent_edges AS g, search_graph AS sg "))
->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.target = sg.source")
->where("depth", "<", $options->parentsDepth)
diff --git a/src/Query/DatabaseGraph/SqliteDatabaseGraph.php b/src/Query/DatabaseGraph/SqliteDatabaseGraph.php
index 423bad0..bf37462 100644
--- a/src/Query/DatabaseGraph/SqliteDatabaseGraph.php
+++ b/src/Query/DatabaseGraph/SqliteDatabaseGraph.php
@@ -13,7 +13,7 @@ class SqliteDatabaseGraph implements DatabaseGraph
*/
public function getChildren(array $ids, QueryOptions $options): array
{
- $subquery = Database::make()->table('edges AS g')
+ $subquery = Database::make()->table('lucent_edges AS g')
->select(DB::raw('g.source,g.target,g.rank,g.sourceSchema,g.targetSchema,g.field, 1 as depth '))
->whereIn('source', $ids);
@@ -23,7 +23,7 @@ class SqliteDatabaseGraph implements DatabaseGraph
$subquery->limit($options->childrenLimit)
->unionAll(
- Database::make()->table(DB::raw("edges AS g, search_graph AS sg "))
+ Database::make()->table(DB::raw("lucent_edges AS g, search_graph AS sg "))
->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.source = sg.target")
->where("depth", "<", $options->childrenDepth)
@@ -41,12 +41,12 @@ class SqliteDatabaseGraph implements DatabaseGraph
*/
public function getParents(array $ids, QueryOptions $options): array
{
- $subquery = Database::make()->table('edges AS g')
+ $subquery = Database::make()->table('lucent_edges AS g')
->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth '))
->limit($options->parentsLimit)
->whereIn('g.target', $ids)
->unionAll(
- Database::make()->table(DB::raw("edges AS g, search_graph AS sg "))
+ Database::make()->table(DB::raw("lucent_edges AS g, search_graph AS sg "))
->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.target = sg.source")
->where("depth", "<", $options->parentsDepth)
diff --git a/src/Query/FilterParser.php b/src/Query/FilterParser.php
index 1d6d987..2ea957b 100644
--- a/src/Query/FilterParser.php
+++ b/src/Query/FilterParser.php
@@ -59,7 +59,7 @@ final class FilterParser
}
$targetIds = collect($graph->records)->pluck("id");
- $sourceIds = Database::make()->table("edges")->whereIn("target", $targetIds)->where("field", $k)->get()->pluck("source");
+ $sourceIds = Database::make()->table("lucent_edges")->whereIn("target", $targetIds)->where("field", $k)->get()->pluck("source");
return array_merge($c, $sourceIds->toArray());
}, []);
diff --git a/src/Query/Query.php b/src/Query/Query.php
index e034c59..3b4edc3 100644
--- a/src/Query/Query.php
+++ b/src/Query/Query.php
@@ -13,9 +13,8 @@ use Lucent\Record\InputFormatter;
use Lucent\Record\QueryRecord;
use Lucent\Record\Record;
-final class Query
+final class Query
{
-
/**
* @var array $filters
*/
@@ -23,11 +22,10 @@ final class Query
public QueryOptions $options;
public function __construct(
- public readonly FilterParser $filterParser,
+ public readonly FilterParser $filterParser,
public readonly InputFormatter $inputFormatter,
- public readonly DatabaseGraph $databaseGraph,
- )
- {
+ public readonly DatabaseGraph $databaseGraph,
+ ) {
$this->options = new QueryOptions();
}
@@ -43,7 +41,6 @@ final class Query
return $this;
}
-
public function run(): Graph
{
$resultsRecords = $this->mainQuery();
@@ -55,33 +52,53 @@ final class Query
$resultChildrenEdges = [];
if ($this->options->childrenDepth > 0 && !empty($ids)) {
$resultChildrenEdges = $this->getChildren($ids);
- $resultChildrenEdgesTargetIds = array_map(fn($e) => $e->target, $resultChildrenEdges);
+ $resultChildrenEdgesTargetIds = array_map(
+ fn($e) => $e->target,
+ $resultChildrenEdges,
+ );
}
$resultParentSourceTargetIds = [];
$resultParentEdges = [];
if ($this->options->parentsDepth > 0 && !empty($ids)) {
$resultParentEdges = $this->getParents($ids);
- $resultParentSourceTargetIds = array_map(fn($e) => $e->source, $resultParentEdges);
+ $resultParentSourceTargetIds = array_map(
+ fn($e) => $e->source,
+ $resultParentEdges,
+ );
}
- $edgesIds = collect($resultParentSourceTargetIds)->merge($resultChildrenEdgesTargetIds)->unique()->values()->toArray();
+ $edgesIds = collect($resultParentSourceTargetIds)
+ ->merge($resultChildrenEdgesTargetIds)
+ ->unique()
+ ->values()
+ ->toArray();
$edgeRecords = [];
if (!empty($edgesIds)) {
- $edgeRecords = Database::make()->table('records')
+ $edgeRecords = Database::make()
+ ->table("lucent_records")
->whereIn("id", $edgesIds)
->whereIn("status", $this->options->status)
- ->get()->toArray();
+ ->get()
+ ->toArray();
}
- $resultsRecordsUnique = collect(array_merge($resultsRecords, $edgeRecords))->unique("id")->values()->toArray();
-// $resultEdges = collect(array_merge($resultChildrenEdges, $resultParentEdges))
-// ->unique(fn($edge) => $edge->source . $edge->target . $edge->field)
-// ->toArray();
+ $resultsRecordsUnique = collect(
+ array_merge($resultsRecords, $edgeRecords),
+ )
+ ->unique("id")
+ ->values()
+ ->toArray();
+ // $resultEdges = collect(array_merge($resultChildrenEdges, $resultParentEdges))
+ // ->unique(fn($edge) => $edge->source . $edge->target . $edge->field)
+ // ->toArray();
- $formattedRecords = $this->formatRecords($resultsRecordsUnique, $resultChildrenEdges, $resultParentEdges);
+ $formattedRecords = $this->formatRecords(
+ $resultsRecordsUnique,
+ $resultChildrenEdges,
+ $resultParentEdges,
+ );
$this->reset();
return $formattedRecords;
-
}
private function reset()
@@ -90,33 +107,41 @@ final class Query
$this->filters = [];
}
- private function formatRecords(array $records, array $edges, array $parentEdges): Graph
- {
- $queryRecords = collect($records)->map(function ($recordData) {
+ private function formatRecords(
+ array $records,
+ array $edges,
+ array $parentEdges,
+ ): Graph {
+ $queryRecords = collect($records)
+ ->map(function ($recordData) {
+ $record = Record::fromDB($recordData);
- $record = Record::fromDB($recordData);
+ $record->data = $this->inputFormatter->fill(
+ $record->schema,
+ $record->data,
+ );
- $record->data = $this->inputFormatter->fill($record->schema, $record->data);
+ $queryRecord = QueryRecord::fromRecord($record);
+ $queryRecord->isRoot = data_get($recordData, "isRoot") === true;
+ return $queryRecord;
+ })
+ ->toArray();
- $queryRecord = QueryRecord::fromRecord($record);
- $queryRecord->isRoot = data_get($recordData, "isRoot") === true;
- return $queryRecord;
- })->toArray();
-
-
- $queryEdges = collect($edges)->map(function ($edgeData) {
-
- return Edge::fromArray((array)$edgeData);
-
- })->sortBy("rank")->values()->toArray();
-
- $queryParentEdges = collect($parentEdges)->map(function ($edgeData) {
-
-
- return Edge::fromArray((array)$edgeData);
-
- })->sortBy("rank")->values()->toArray();
+ $queryEdges = collect($edges)
+ ->map(function ($edgeData) {
+ return Edge::fromArray((array) $edgeData);
+ })
+ ->sortBy("rank")
+ ->values()
+ ->toArray();
+ $queryParentEdges = collect($parentEdges)
+ ->map(function ($edgeData) {
+ return Edge::fromArray((array) $edgeData);
+ })
+ ->sortBy("rank")
+ ->values()
+ ->toArray();
return new Graph(
new Collection($queryRecords),
@@ -126,13 +151,11 @@ final class Query
);
}
-
public function tree(): Collection
{
return $this->run()->tree();
}
-
private function parseFilters(Builder $query): Builder
{
foreach ($this->filters as $filter) {
@@ -142,10 +165,9 @@ final class Query
return $query;
}
-
private function mainQuery(): array
{
- $query = Database::make()->table("records");
+ $query = Database::make()->table("lucent_records");
$query = $this->parseFilters($query);
$query = $this->findNotLinked($query);
@@ -155,13 +177,15 @@ final class Query
}
$query = $this->orderByQuery($query);
- return $query->get()->map(function ($r) {
- $r->isRoot = true;
- return $r;
- })->toArray();
+ return $query
+ ->get()
+ ->map(function ($r) {
+ $r->isRoot = true;
+ return $r;
+ })
+ ->toArray();
}
-
private function findNotLinked(Builder $query): Builder
{
if (empty($this->options->notLinked)) {
@@ -170,14 +194,19 @@ final class Query
// This returns only records that have no parents
$query
- ->select("records.*")
- ->join('edges', 'records.id', '=', 'edges.target', 'left outer')
- ->whereNull("edges.target");
+ ->select("lucent_records.*")
+ ->join(
+ "lucent_edges",
+ "lucent_records.id",
+ "=",
+ "lucent_edges.target",
+ "left outer",
+ )
+ ->whereNull("lucent_edges.target");
return $query;
}
- private
- function getChildren(array $ids): array
+ private function getChildren(array $ids): array
{
return $this->databaseGraph->getChildren($ids, $this->options);
}
@@ -187,12 +216,9 @@ final class Query
return $this->databaseGraph->getParents($ids, $this->options);
}
-
- public
- function runWithCount(): Graph
+ public function runWithCount(): Graph
{
-
- $query = Database::make()->table("records");
+ $query = Database::make()->table("lucent_records");
$query = $this->parseFilters($query);
$query = $this->findNotLinked($query);
$graph = $this->run();
@@ -200,15 +226,13 @@ final class Query
return $graph;
}
-
public function limit(int $limit): Query
{
$this->options->limit = $limit;
return $this;
}
- public
- function skip(int $skip): Query
+ public function skip(int $skip): Query
{
$this->options->skip = $skip;
return $this;
@@ -250,7 +274,6 @@ final class Query
return $this;
}
-
public function sort(string $sort): Query
{
$this->options->sort[] = $sort;
@@ -269,12 +292,11 @@ final class Query
return $this;
}
- public
- function orderByQuery(Builder $query): Builder
+ public function orderByQuery(Builder $query): Builder
{
foreach ($this->options->sort as $item) {
- $field = str_replace(".", "->", ltrim($item, '-'));
- $dir = str_starts_with($item, '-') ? "desc" : "asc";
+ $field = str_replace(".", "->", ltrim($item, "-"));
+ $dir = str_starts_with($item, "-") ? "desc" : "asc";
if ($field) {
$query->orderBy($field, $dir);
}
diff --git a/src/Record/RecordRepo.php b/src/Record/RecordRepo.php
index a8dcd89..360d77a 100644
--- a/src/Record/RecordRepo.php
+++ b/src/Record/RecordRepo.php
@@ -6,16 +6,13 @@ use Lucent\Database\Database;
class RecordRepo
{
- public function __construct()
- {
- }
+ public function __construct() {}
public static function create(Record $record): void
{
$recordToDB = $record->toDB();
- Database::make()->table("records")->insert($recordToDB);
-
+ Database::make()->table("lucent_records")->insert($recordToDB);
}
/**
@@ -23,40 +20,55 @@ class RecordRepo
*/
public static function updateStatusBulk(Status $status, array $ids): void
{
- Database::make()->table("records")->whereIn("id", $ids)->update([
- 'status' => $status->value
- ]);
+ Database::make()
+ ->table("lucent_records")
+ ->whereIn("id", $ids)
+ ->update([
+ "status" => $status->value,
+ ]);
}
public static function update(Record $record): void
{
$recordToDB = $record->toDB();
- Database::make()->table("records")->where("id", $record->id)->update($recordToDB);
+ Database::make()
+ ->table("lucent_records")
+ ->where("id", $record->id)
+ ->update($recordToDB);
}
-
/**
* @param string[] $ids
*/
- public function deleteMany(
- array $ids,
- ): void
+ public function deleteMany(array $ids): void
{
-
- Database::make()->table("records")->whereIn("id", $ids)->delete();
- Database::make()->table("edges")->whereIn("source", $ids)->delete();
- Database::make()->table("edges")->whereIn("target", $ids)->delete();
- Database::make()->table("revisions")->whereIn("recordId", $ids)->delete();
+ Database::make()
+ ->table("lucent_records")
+ ->whereIn("id", $ids)
+ ->delete();
+ Database::make()
+ ->table("lucent_edges")
+ ->whereIn("source", $ids)
+ ->delete();
+ Database::make()
+ ->table("lucent_edges")
+ ->whereIn("target", $ids)
+ ->delete();
+ Database::make()
+ ->table("lucent_revisions")
+ ->whereIn("recordId", $ids)
+ ->delete();
}
- public function deleteTrashedBySchema(
- string $schemaName,
- ): void
+ public function deleteTrashedBySchema(string $schemaName): void
{
- $ids = Database::make()->table("records")
+ $ids = Database::make()
+ ->table("lucent_records")
->where("schema", $schemaName)
->where("status", Status::TRASHED->value)
- ->get()->pluck("id")->toArray();
+ ->get()
+ ->pluck("id")
+ ->toArray();
$this->deleteMany($ids);
}
diff --git a/src/Record/RecordService.php b/src/Record/RecordService.php
index c3f29bf..c39cb64 100644
--- a/src/Record/RecordService.php
+++ b/src/Record/RecordService.php
@@ -23,20 +23,17 @@ use Lucent\Schema\Validator\ValidatorException;
readonly class RecordService
{
-
public function __construct(
- private AuthService $authService,
+ private AuthService $authService,
private RevisionService $revisionService,
- private ChannelService $channelService,
- private Validator $recordValidator,
- private Query $query,
- private InputFormatter $inputFormatter,
- private RecordRepo $recordRepo,
- private EdgeService $edgeService,
- private FileService $fileService,
- )
- {
- }
+ private ChannelService $channelService,
+ private Validator $recordValidator,
+ private Query $query,
+ private InputFormatter $inputFormatter,
+ private RecordRepo $recordRepo,
+ private EdgeService $edgeService,
+ private FileService $fileService,
+ ) {}
/**
* @param string $url
@@ -47,14 +44,15 @@ readonly class RecordService
* @throws ValidatorException
*/
public function createFromUrl(
- string $url,
+ string $url,
RecordInputData $data,
- array $edges
- ): string
- {
+ array $edges,
+ ): string {
$schema = $this->channelService->getSchema($data->schemaName)->get();
if ($schema->type !== Type::FILES) {
- throw new LucentException("You can't upload a file to a regular record");
+ throw new LucentException(
+ "You can't upload a file to a regular record",
+ );
}
$fileData = $this->fileService->createFromUrl($schema, $url);
if ($fileData->isDuplicate) {
@@ -64,14 +62,15 @@ readonly class RecordService
}
public function createFromUploadedFile(
- UploadedFile $uploadedFile,
+ UploadedFile $uploadedFile,
RecordInputData $data,
- array $edges
- ): string
- {
+ array $edges,
+ ): string {
$schema = $this->channelService->getSchema($data->schemaName)->get();
if ($schema->type !== Type::FILES) {
- throw new LucentException("You can't upload a file to a regular record");
+ throw new LucentException(
+ "You can't upload a file to a regular record",
+ );
}
$fileData = $this->fileService->upload($schema, $uploadedFile);
if ($fileData->isDuplicate) {
@@ -81,14 +80,15 @@ readonly class RecordService
}
public function createFromFileData(
- FileData $fileData,
+ FileData $fileData,
RecordInputData $data,
- array $edges
- ): string
- {
+ array $edges,
+ ): string {
$schema = $this->channelService->getSchema($data->schemaName)->get();
if ($schema->type !== Type::FILES) {
- throw new LucentException("You can't upload a file to a regular record");
+ throw new LucentException(
+ "You can't upload a file to a regular record",
+ );
}
return $this->create($data, $fileData, $edges);
}
@@ -102,12 +102,13 @@ readonly class RecordService
*/
public function create(
RecordInputData $data,
- ?FileData $file = null,
- array $edges = []
- ): string
- {
-
- $formattedData = $this->inputFormatter->fill($data->schemaName, new RecordData($data->data));
+ ?FileData $file = null,
+ array $edges = [],
+ ): string {
+ $formattedData = $this->inputFormatter->fill(
+ $data->schemaName,
+ new RecordData($data->data),
+ );
$newRecordId = empty($data->id) ? Id::new() : $data->id;
$record = new Record(
@@ -120,38 +121,49 @@ readonly class RecordService
);
if ($data->status === Status::PUBLISHED) {
- $errors = $this->recordValidator->check($data->schemaName, $record->data);
+ $errors = $this->recordValidator->check(
+ $data->schemaName,
+ $record->data,
+ );
if ($errors->isNotEmpty()) {
$this->recordValidator->throwException($errors);
}
}
RecordRepo::create($record);
- $newEdges = $this->edgeService->createManyForRecord($record->id, $record->schema, $edges);
+ $newEdges = $this->edgeService->createManyForRecord(
+ $record->id,
+ $record->schema,
+ $edges,
+ );
$this->revisionService->create($record, $newEdges);
return $record->id;
-
}
/**
* @throws LucentException
* @throws ValidatorException
*/
- public function update(
- string $id,
- array $data,
- Status $status,
- ): void
+ public function update(string $id, array $data, Status $status): void
{
- $record = $this->query->filter(["id" => $id])->run()->records->first();
+ $record = $this->query
+ ->filter(["id" => $id])
+ ->run()
+ ->records->first();
if (empty($record)) {
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),
+ );
if ($status === Status::PUBLISHED) {
- $errors = $this->recordValidator->check($record->schema, $formattedData);
+ $errors = $this->recordValidator->check(
+ $record->schema,
+ $formattedData,
+ );
if ($errors->isNotEmpty()) {
$this->recordValidator->throwException($errors);
}
@@ -169,7 +181,6 @@ readonly class RecordService
RecordRepo::update($newRecord);
$newEdges = $this->edgeService->findForSource($record->id);
$this->revisionService->create($newRecord, $newEdges);
-
}
/**
@@ -178,20 +189,28 @@ readonly class RecordService
*/
public function updateWithEdges(
string $id,
- array $data,
+ array $data,
Status $status,
- array $edges
- ): void
- {
- $record = $this->query->filter(["id" => $id])->run()->records->first();
+ array $edges,
+ ): void {
+ $record = $this->query
+ ->filter(["id" => $id])
+ ->run()
+ ->records->first();
if (empty($record)) {
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),
+ );
if ($status === Status::PUBLISHED) {
- $errors = $this->recordValidator->check($record->schema, $formattedData);
+ $errors = $this->recordValidator->check(
+ $record->schema,
+ $formattedData,
+ );
if ($errors->isNotEmpty()) {
$this->recordValidator->throwException($errors);
}
@@ -207,15 +226,15 @@ readonly class RecordService
);
RecordRepo::update($newRecord);
- $newEdges = $this->edgeService->replaceManyForRecord($record->id, $record->schema, $edges);
+ $newEdges = $this->edgeService->replaceManyForRecord(
+ $record->id,
+ $record->schema,
+ $edges,
+ );
$this->revisionService->create($newRecord, $newEdges);
-
}
- public function changeStatusBulk(
- string $status,
- array $recordsIds,
- ): void
+ public function changeStatusBulk(string $status, array $recordsIds): void
{
RecordRepo::updateStatusBulk(Status::from($status), $recordsIds);
}
@@ -224,10 +243,7 @@ readonly class RecordService
* @throws LucentException
* @throws ValidatorException
*/
- public
- function clone(
- string $recordId,
- ): string
+ public function clone(string $recordId): string
{
$graph = $this->query
->filter(["id" => $recordId])
@@ -240,15 +256,18 @@ readonly class RecordService
throw new LucentException("Record id is missing");
}
- $newRecordId = (string)Str::uuid();
+ $newRecordId = (string) Str::uuid();
$newEdgesData = $graph->edges
->filter(fn(Edge $edge) => $edge->source == $recordId)
->values()
- ->map(fn(Edge $edge) => new EdgeInputData(
- target: $edge->target,
- targetSchema: $edge->targetSchema,
- field: $edge->field,
- ))->toArray();
+ ->map(
+ fn(Edge $edge) => new EdgeInputData(
+ target: $edge->target,
+ targetSchema: $edge->targetSchema,
+ field: $edge->field,
+ ),
+ )
+ ->toArray();
$record->id = $newRecordId;
@@ -257,62 +276,62 @@ readonly class RecordService
schemaName: $record->schema,
id: $record->id,
data: $record->data->toArray(),
- status: Status::DRAFT
+ status: Status::DRAFT,
),
file: $record->_file,
- edges: $newEdgesData
+ edges: $newEdgesData,
);
-
}
-
- public function deleteMany(
- array $recordsIds,
- ): void
+ public function deleteMany(array $recordsIds): void
{
$this->recordRepo->deleteMany($recordsIds);
}
- public function emptyTrash(
- string $schemaName,
- ): void
+ public function emptyTrash(string $schemaName): void
{
-
$schema = $this->channelService->getSchema($schemaName)->get();
$this->recordRepo->deleteTrashedBySchema($schemaName);
}
-
/**
* @throws LucentException
* @throws ValidatorException
*/
- public function rollback(
- string $recordId,
- int $version,
- ): void
+ public function rollback(string $recordId, int $version): void
{
- $revision = $this->revisionService->getByRecordIdAndVersion($recordId, $version)->get();
+ $revision = $this->revisionService
+ ->getByRecordIdAndVersion($recordId, $version)
+ ->get();
$this->updateWithEdges(
id: $revision->recordId,
data: $revision->data->toArray(),
status: Status::DRAFT,
- edges: array_map(fn(Edge $edge) => new EdgeInputData($edge->target, $edge->targetSchema, $edge->field), $revision->_edges),
+ edges: array_map(
+ fn(Edge $edge) => new EdgeInputData(
+ $edge->target,
+ $edge->targetSchema,
+ $edge->field,
+ ),
+ $revision->_edges,
+ ),
);
}
-
- public function createEmpty(
- Schema $schema,
- ): Record
+ public function createEmpty(Schema $schema): Record
{
-
- $defaultValues = $schema->fields->reduce(function ($carry, FieldInterface $f) {
+ $defaultValues = $schema->fields->reduce(function (
+ $carry,
+ FieldInterface $f,
+ ) {
$carry[$f->name] = $f->default ?? null;
return $carry;
}, []);
- $formattedData = $this->inputFormatter->fill($schema->name, new RecordData($defaultValues));
+ $formattedData = $this->inputFormatter->fill(
+ $schema->name,
+ new RecordData($defaultValues),
+ );
return new Record(
id: Id::new(),
@@ -322,6 +341,5 @@ readonly class RecordService
data: $formattedData,
_file: null,
);
-
}
}
diff --git a/src/Revision/RevisionRepo.php b/src/Revision/RevisionRepo.php
index 697d27d..bbac73f 100644
--- a/src/Revision/RevisionRepo.php
+++ b/src/Revision/RevisionRepo.php
@@ -14,7 +14,7 @@ use stdClass;
class RevisionRepo
{
- private string $table = "revisions";
+ private string $table = "lucent_revisions";
public function create(Revision $revision): string
{
diff --git a/src/Setup/Step/DatabaseSetupStep.php b/src/Setup/Step/DatabaseSetupStep.php
index aa63d7f..3fde891 100644
--- a/src/Setup/Step/DatabaseSetupStep.php
+++ b/src/Setup/Step/DatabaseSetupStep.php
@@ -8,53 +8,23 @@ use Lucent\Setup\Data\SetupStep;
class DatabaseSetupStep implements IStep
{
-
public function __invoke(): SetupStep
{
-
-
$name = "Database Connection";
- $databaseConnectionName = config("lucent.database");
-
-
- $databaseConfig = config('database.connections.'.$databaseConnectionName);
-
- if (empty($databaseConfig)) {
- $instructions = << [
- '$databaseConnectionName' => [
- 'driver' => 'sqlite',
- 'url' => env('LUCENT_DATABASE_URL'),
- 'database' => env('LUCENT_DB_DATABASE', database_path('database.sqlite')),
- 'prefix' => '',
- 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
- ],
-EOD;
- return SetupStep::makeFail($name, $instructions);
- }
-
-
- if(!in_array($driver = $databaseConfig["driver"],["sqlite","pgsql"])){
- $instructions = <<table("records")->get();
+ Database::make()->table("lucent_records")->get();
} catch (QueryException $e) {
$instructions = <<authService->getCurrentUser());
$context["view"] = $view;
$context["layout"] = $layout;
$context["title"] = $title;
$context["data"] = $data;
$context["channel"] = $this->channelService->channel;
- $context["readableSchemas"] = $this->accountService->currentReadableSchemas();
+ $context[
+ "readableSchemas"
+ ] = $this->accountService->currentReadableSchemas();
$json = json_encode($context);
- $divTag = sprintf('', $layout);
- $jsonTag = sprintf('', $layout, $json);
+ $divTag = sprintf(
+ '',
+ $layout,
+ );
+ $jsonTag = sprintf(
+ '',
+ $layout,
+ $json,
+ );
$svelte = $divTag . $jsonTag;
- return view('lucent::svelte', [
- 'svelte' => $svelte,
- 'view' => $view,
- 'data' => $data,
- 'title' => $title,
- 'layout' => $layout,
- 'channel' => $this->channelService->channel,
+ return view("lucent::svelte", [
+ "svelte" => $svelte,
+ "view" => $view,
+ "data" => $data,
+ "title" => $title,
+ "layout" => $layout,
+ "channel" => $this->channelService->channel,
]);
}
-
}
-