This commit is contained in:
2023-10-02 23:10:49 +03:00
commit c6cb488379
255 changed files with 18731 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
<?php
namespace Lucent\Http\Controller;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Lucent\Account\Auth;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
use function Lucent\Svelte\svelte;
class AccountController extends Controller
{
public function profile()
{
return svelte(
layout: "account",
view: "profile",
title: "Profile",
data: []
);
}
public function updateName(Request $request)
{
try {
(new Auth)->updateName(session("user.id"), $request->input("name"));
} catch (\Throwable $th) {
return fail($th);
}
return ok();
}
public function updateEmail(Request $request)
{
try {
(new Auth)->updateEmail(session("user.id"), $request->input("email"));
} catch (\Throwable $th) {
return fail($th);
}
return ok();
}
}
@@ -0,0 +1,51 @@
<?php
namespace Lucent\Http\Controller\Api;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Lucent\Account\AuthService;
use Lucent\LucentException;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
use function Lucent\Svelte\svelte;
class AccountController extends Controller
{
public function __construct(
private readonly AuthService $authService,
)
{
}
public function profile(): View
{
return svelte(
layout: "account",
view: "profile",
title: "Profile",
data: []
);
}
public function updateName(Request $request): Response
{
try {
$this->authService->updateName(session("user.id"), $request->input("name"));
} catch (LucentException $th) {
return fail($th);
}
$request->session()->put("user.name", $request->input("name"));
return ok();
}
}
@@ -0,0 +1,37 @@
<?php
namespace Lucent\Http\Controller\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Lucent\Edge\EdgeService;
use Lucent\LucentException;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
class EdgeController extends Controller
{
public function create(Request $request): Response
{
try {
$edge = EdgeService::create(
source: $request->input("source"),
target: $request->input("target"),
sourceSchema: $request->input("sourceSchema"),
targetSchema: $request->input("targetSchema"),
field: $request->input("field"),
rank: $request->input("rank") ?? "",
);
} catch (LucentException $th) {
return fail($th);
}
return ok([
"edge" => $edge,
]);
}
}
@@ -0,0 +1,39 @@
<?php
namespace Lucent\Http\Controller\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Lucent\Channel\ChannelContext;
use Lucent\Schema\FieldRepo;
use Lucent\Schema\SchemaRepo;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
class FieldController extends Controller
{
public function create(Request $request)
{
try {
$schema = SchemaRepo::findByName($request->input("schema"));
FieldRepo::create($schema, $request->input("field"));
} catch (\Throwable $th) {
return fail($th);
}
return ok();
}
public function update(Request $request)
{
try {
$schema = SchemaRepo::findByName($request->input("schema"));
FieldRepo::update($schema, $request->input("field"));
} catch (\Throwable $th) {
return fail($th);
}
return ok();
}
}
@@ -0,0 +1,62 @@
<?php
namespace Lucent\Http\Controller\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Lucent\Account\AuthService;
use Lucent\Channel\ChannelRepo;
use Lucent\File\FileUploadResult;
use Lucent\Query\Query;
use Lucent\Record\RecordService;
use function Lucent\File\uploadFile;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
class FileController extends Controller
{
public function __construct(
private readonly RecordService $recordService,
private readonly Query $query
)
{
}
public function upload(Request $request)
{
$validator = Validator::make(request()->all(), [
'files.*' => 'required|file|max:100000',
]);
if ($validator->fails()) {
return fail($validator->errors()->first());
}
$channel = ChannelRepo::current();
$schema = $channel->schemas->firstWhere("name", $request->input("schema"));
$files = request()->file('files');
$uploadResults = collect($files)->map(fn($file) => uploadFile($schema, $file))->toArray();
$insertedIds = collect($uploadResults)
->filter(fn(FileUploadResult $res) => !$res->isDuplicate)
->values()
->map(function (FileUploadResult $uploadResult) use ($schema, $request) {
return $this->recordService->create(
userId: AuthService::currentUserId($request),
schemaName: $schema->name,
data: [],
file: (array)$uploadResult->recordFile,
edges: [],
status: $request->input("status") ?? "published",
uploadFromUrl: ""
);
})->toArray();
return ok($insertedIds);
}
}
@@ -0,0 +1,107 @@
<?php
namespace Lucent\Http\Controller\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Lucent\Channel\ChannelRepo;
use Lucent\LucentException;
use Lucent\Query\Query;
use Lucent\Record\RecordService;
use Lucent\Schema\Validator\ValidatorException;
use Throwable;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
class RecordController extends Controller
{
public function __construct(
private readonly RecordService $recordService,
private readonly Query $query
)
{
}
public function records(Request $request)
{
$channel = ChannelRepo::current();
$urlParams = $request->all();
$sort = data_get($urlParams, "sort") ?? "-_sys.updatedAt";
$filter = data_get($urlParams, "filter") ?? [];
$arguments = array_merge([
], $filter);
$skip = data_get($urlParams, "skip") ?? 0;
$limit = data_get($urlParams, "limit") ?? 15;
$queryResult = $this->query
->filter($arguments)
->limit($limit)
->skip($skip)
->sort($sort)
->childrenDepth($request->input("childrenDepth") ?? 1)
->parentsDepth($request->input("parentsDepth") ?? 0)
->runWithCount();
$graph = $queryResult->getQueryRecords($channel->schemas);
$total = $queryResult->getTotal();
return ok([
"graph" => $graph->toArray(),
"sort" => $sort,
"limit" => $limit,
"skip" => $skip,
"total" => $total,
]);
}
public function create(Request $request)
{
try {
$recordId = $this->recordService->create(
userId: $request->input("userId"),
schemaName: $request->input("schema"),
data: $request->input("data") ?? [],
file: $request->input("file") ?? [],
edges: $request->input("edges") ?? [],
status: $request->input("status") ?? "draft",
uploadFromUrl: $request->input("uploadFromUrl") ?? ""
);
} catch (ValidatorException $th) {
return fail($th->getValidatorErrors());
} catch (LucentException $th) {
return fail($th);
}
return ok(["id" => $recordId]);
}
public function update(Request $request)
{
try {
$this->recordService->update(
userId: $request->input("userId"),
id: $request->route("id"),
data: $request->input("data"),
status: $request->input("status"),
edges: $request->input("edges") ?? [],
updateEdges: false,
);
} catch (ValidatorException $th) {
return fail($th->getValidatorErrors());
} catch (LucentException $th) {
return fail($th);
} catch (Throwable $th) {
if ($th->getCode() == 11000) {
return fail("ID has to be unique in the channel");
}
return fail($th);
}
return ok();
}
}
@@ -0,0 +1,81 @@
<?php
namespace Lucent\Http\Controller\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Lucent\Schema\SchemaService;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
class SchemaController extends Controller
{
public function __construct(
private readonly SchemaService $schemaService
)
{
}
// public function find(Request $request)
// {
// $cid = $request->header("CHANNEL-ID");
// $channelContext = ChannelContext::fromId($cid)->withSchemas();
// return ok($channelContext->getSchemas());
// }
// public function findOne(Request $request, string $name)
// {
// $cid = $request->header("CHANNEL-ID");
// $channelContext = ChannelContext::fromId($cid)->withSchemas();
// $schema = SchemaRepo::context($channelContext)->findByName($name);
// return ok($schema->toArray());
// }
public function create(Request $request)
{
try {
$schema = $this->schemaService->create(
name: $request->input("name"),
label: $request->input("label"),
type: $request->input("type"),
isEntry: $request->input("isEntry"),
revisionRetentionDays: $request->input("revisionRetentionDays"),
revisionRetentionNumber: $request->input("revisionRetentionNumber"),
trashedRetentionDays: $request->input("trashedRetentionDays"),
fields: $request->input("fields"),
titleTemplate: $request->input("titleTemplate") ?? "",
visible: $request->input("visible") ?? [],
path: $request->input("path") ?? "",
);
} catch (\Throwable $th) {
return fail($th);
}
return ok($schema->toArray());
}
// public function update(Request $request)
// {
// $cid = $request->header("CHANNEL-ID");
// try {
// $channelContext = ChannelContext::fromId($cid);
// SchemaRepo::context($channelContext)->update($request->all());
// } catch (\Throwable $th) {
// return fail($th);
// }
// $schema = SchemaRepo::context($channelContext)->findByName($request->input("name"));
// return ok($schema->toArray());
// }
public function delete(Request $request)
{
try {
$this->schemaService->delete($request->route("name"));
} catch (\Throwable $th) {
return fail($th);
}
return ok();
}
}
+126
View File
@@ -0,0 +1,126 @@
<?php
namespace Lucent\Http\Controller;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Lucent\Account\AuthService;
use Lucent\Account\UserRepo;
use Lucent\LucentException;
use Lucent\Svelte\Svelte;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
class AuthController extends Controller
{
public function __construct(
private readonly AuthService $authService,
private readonly Svelte $svelte,
private readonly UserRepo $userRepo,
)
{
}
public function register(Request $request): View
{
$userCount = $this->userRepo->count();
$email = $request->input("email");
$token = $request->input("token");
return svelte(
layout: "account",
view: "register",
title: "Create an account",
data: [
'email' => $email,
'token' => $token,
'userCount' => $userCount
]
);
}
public function postRegister(Request $request): Response
{
try {
if ($request->input("isAdmin")) {
$this->authService->registerAdmin(
name: $request->input("name"),
password: $request->input("password"),
email: $request->input("email"),
);
} else {
$this->authService->register(
name: $request->input("name"),
password: $request->input("password"),
email: $request->input("email"),
token: $request->input("token") ?? "",
);
}
} catch (LucentException $th) {
return fail($th);
}
return ok();
}
public function login(): View
{
return $this->svelte->render(
layout: "account",
view: "login",
title: "Log in"
);
}
public function postLogin(Request $request): Response
{
try {
$this->authService->sendLoginEmail($request->input("email"));
} catch (LucentException $th) {
return fail($th);
}
return ok();
}
public function verify(Request $request): View
{
return $this->svelte->render(
layout: "account",
view: "verify",
title: "Verify and enter",
data: [
"email" => $request->input("email"),
"token" => $request->input("token"),
]
);
}
public function postVerify(Request $request): Response
{
try {
$this->authService->login($request->input("email"), $request->input("token"));
} catch (LucentException $th) {
return fail($th);
}
return ok();
}
public function logout(): RedirectResponse
{
session()->flush();
return redirect("/login");
}
}
+15
View File
@@ -0,0 +1,15 @@
<?php
namespace Lucent\Http\Controller;
use App\Http\Controllers\Controller;
use Lucent\Account\Auth;
use Lucent\Channel\ChannelContext;
use Lucent\Query\Options;
use Lucent\Query\Reference;
class EdgeController extends Controller
{
}
+138
View File
@@ -0,0 +1,138 @@
<?php
namespace Lucent\Http\Controller;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Intervention\Image\ImageManager;
use Lucent\Channel\ChannelRepo;
use Lucent\Channel\ChannelService;
use Lucent\File\FileUploadResult;
use Lucent\Query\Query;
use Lucent\Record\RecordService;
use function Lucent\File\loadDisk;
use function Lucent\File\uploadFile;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
class FileController extends Controller
{
public function __construct(
private readonly ChannelService $channelService,
private readonly RecordService $recordService,
private readonly Query $query
)
{
}
public function download(Request $request)
{
$disk = loadDisk();
return $disk->download($request->input("path"));
}
public function get(Request $request)
{
$manager = new ImageManager(['driver' => 'imagick']);
$filesystem = loadDisk();
$path = $request->route("path");
if ($filesystem->exists($path)) {
$image = $manager->make($filesystem->get($path));
return $image->response();
}
$arr = explode(".", $path);
$ext = end($arr);
$pathWithoutExtension = str_replace("." . $ext, "", $path);
$pathArguments = (function ($path) {
$pathWithArgumentsAr = explode("-", $path);
return collect($pathWithArgumentsAr)
->filter(fn($ar) => str_contains($ar, "_"))
->reduce(function ($carry, $arg) {
[$k, $v] = explode("_", $arg);
$carry[$k] = $v;
return $carry;
});
})($pathWithoutExtension);
$originalPath = (function ($path) use ($ext) {
$arr = explode("-o-", $path);
return $arr[0] . "." . $ext;
})($path);
$image = $manager->make($filesystem->get($originalPath));
if (empty($pathArguments["mode"])) {
if (empty($pathArguments["w"])) {
$image->resize(null, $pathArguments["h"], function ($constraint) {
$constraint->aspectRatio();
});
} elseif (empty($pathArguments["h"])) {
$image->resize($pathArguments["w"], null, function ($constraint) {
$constraint->aspectRatio();
});
} else {
$image->resize($pathArguments["w"], $pathArguments["h"]);
}
} else if ($pathArguments["mode"] === "fit") {
$image->fit($pathArguments["w"], $pathArguments["h"]);
}
$disk = loadDisk();
// $disk->put("cache/" . $path, $image);
$image->save(storage_path("app/public/cache/" . $path));
return $image->response();
}
public function upload(Request $request)
{
$validator = Validator::make(request()->all(), [
'files.*' => 'required|file|max:100000',
]);
if ($validator->fails()) {
return fail($validator->errors()->first());
}
$schema = $this->channelService->channel->schemas->firstWhere("name", $request->input("schema"));
$files = request()->file('files');
$uploadResults = collect($files)->map(fn($file) => uploadFile($schema, $file))->toArray();
collect($uploadResults)
->filter(fn(FileUploadResult $res) => !$res->isDuplicate)
->values()
->map(function (FileUploadResult $uploadResult) use ($schema) {
return $this->recordService->create(
schemaName: $schema->name,
data: [],
file: (array)$uploadResult->recordFile,
edges: [],
status: "published",
uploadFromUrl: ""
);
})->toArray();
$queryResult = $this->query
->filter([
"_sys.schema" => $schema->name
])
->limit(15)
->skip(0)
->sort("-_sys.updatedAt")
->childrenDepth(0)
->parentsDepth(0)
->run();
$graph = $queryResult->getQueryRecords();
return ok($graph->records->toArray());
}
}
+50
View File
@@ -0,0 +1,50 @@
<?php
namespace Lucent\Http\Controller;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Lucent\Schema\FolderRepo;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
class FolderController extends Controller
{
public function create(Request $request)
{
try {
$folder = FolderRepo::create($request->input("name"));
} catch (\Lucent\LucentException $th) {
return fail($th);
}
return ok((array)$folder);
}
public function update(Request $request, string $cid)
{
try {
$folder = FolderRepo::update(
id: $request->input("id"),
name: $request->input("name"),
);
} catch (\Lucent\LucentException $th) {
return fail($th);
}
return ok((array)$folder);
}
public function delete(Request $request, string $cid, string $folderid)
{
try {
FolderRepo::delete($folderid);
} catch (\Lucent\LucentException $th) {
return fail($th);
}
return redirect()->back();
}
}
+68
View File
@@ -0,0 +1,68 @@
<?php
namespace Lucent\Http\Controller;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Lucent\Account\UserRepo;
use Lucent\Channel\ChannelService;
use Lucent\Query\Query;
use Lucent\Svelte\Svelte;
use function Lucent\Response\ok;
class HomeController extends Controller
{
public function __construct(
private readonly ChannelService $channelService,
private readonly Svelte $svelte,
private readonly UserRepo $userRepo,
private readonly Query $query,
)
{
}
public function home(): View
{
return $this->svelte->render(
layout: "channel",
view: "homeIndex",
title: "Records",
);
}
public function records(Request $request): Response
{
$urlParams = $request->all();
$sort = data_get($urlParams, "sort") ?? "-_sys.updatedAt";
$filter = data_get($urlParams, "filter") ?? [];
$arguments = array_merge([
"_sys.status_in" => ["draft", "published"]
], $filter);
$limit = 30;
$queryResult = $this->query
->filter($arguments)
->limit($limit)
->childrenDepth(1)
->parentsDepth(0)
->sort($sort)
->run();
$graph = $queryResult->getQueryRecords();
$users = $this->userRepo->all();
return ok([
"users" => $users,
"records" => $graph->getRootRecords()->toArray(),
"graph" => $graph->toArray(),
"modalUrl" => $request->fullUrl(),
]);
}
}
+70
View File
@@ -0,0 +1,70 @@
<?php
namespace Lucent\Http\Controller;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Lucent\Account\AccountService;
use Lucent\Account\AuthService;
use Lucent\Account\Role;
use Lucent\LucentException;
use Lucent\Svelte\Svelte;
use function Lucent\Response\fail;
class MemberController extends Controller
{
public function __construct(
private readonly AuthService $authService,
private readonly AccountService $accountService,
private readonly Svelte $svelte,
)
{
}
public function index()
{
return $this->svelte->render(
layout: "channel",
view: "members",
title: "Members",
data: [
"users" => $this->accountService->allProfiles()->toArray(),
"roles" => Role::cases()
]
);
}
public function invite(Request $request)
{
if (empty($request->input("role"))) {
return fail("Select a role for the user");
}
try {
$user = $this->authService->invite($request->input("name"), $request->input("email"), $request->input("role"));
} catch (LucentException $th) {
return fail($th);
}
return [
"user" => $user
];
}
public function update(Request $request)
{
try {
$this->authService->changeRole($request->input("id"), $request->input("role"));
} catch (LucentException $th) {
return fail($th);
}
return [
"users" => $this->accountService->allProfiles()->toArray(),
];
}
}
+386
View File
@@ -0,0 +1,386 @@
<?php
namespace Lucent\Http\Controller;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Lucent\Account\AccountService;
use Lucent\Account\AuthService;
use Lucent\Account\UserRepo;
use Lucent\Channel\ChannelService;
use Lucent\Field\System;
use Lucent\LucentException;
use Lucent\Query\Operator;
use Lucent\Query\Query;
use Lucent\Record\Manager;
use Lucent\Record\QueryRecord;
use Lucent\Record\RecordService;
use Lucent\Schema\Validator\ValidatorException;
use Lucent\Svelte\Svelte;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
class RecordController extends Controller
{
public function __construct(
private readonly RecordService $recordService,
private readonly AccountService $accountService,
private readonly AuthService $authService,
private readonly ChannelService $channelService,
private readonly Svelte $svelte,
private readonly UserRepo $userRepo,
private readonly Query $query,
private readonly Manager $recordManager
)
{
}
public function index(Request $request)
{
$schemaName = $request->route("schemaName");
$users = $this->accountService->all();
$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([
"_sys.schema" => $schema->name,
"_sys.status_in" => "draft,published",
], $filter);
$skip = data_get($urlParams, "skip") ?? 0;
$limit = 15;
$records = [];
$graphArray = null;
$total = 0;
try {
$queryResult = $this->query
->filter($arguments)
->limit($limit)
->status(explode(",", $arguments["_sys.status_in"]))
->skip($skip)
->sort($sort)
->childrenDepth(1)
->parentsDepth(0)
->runWithCount();
$graph = $queryResult->getQueryRecords();
$graphArray = $graph->toArray();
$total = $queryResult->getTotal();
$records = $graph->getRootRecords()->toArray();
} catch (SubqueryNoResultException) {
}
$data = [
"schemas" => $this->channelService->channel->schemas,
"schema" => $schema,
"users" => $users,
"records" => $records,
"graph" => $graphArray,
"systemFields" => array_values(System::list()),
"operators" => array_values(Operator::list()),
"sort" => $sort,
"limit" => $limit,
"skip" => $skip,
"total" => $total,
"filter" => $request->input("filter") ?? [],
"inModal" => true,
];
if ($request->ajax()) {
$data["modalUrl"] = $request->fullUrl();
return $data;
}
$data["inModal"] = false;
return $this->svelte->render(
layout: "channel",
view: "contentIndex",
title: "Records",
data: $data
);
}
public function exportCSV(Request $request)
{
$schemaName = $request->route("schemaName");
$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([
"_sys.schema" => $schema->name,
"_sys.status_in" => "draft,published",
], $filter);
$records = [];
try {
$queryResult = $this->query
->filter($arguments)
// ->limit($limit)
->status(explode(",", $arguments["_sys.status_in"]))
// ->skip($skip)
->sort($sort)
->childrenDepth(0)
->parentsDepth(0)
->run();
$graph = $queryResult->getQueryRecords();
$records = $graph->getRootRecords()->toArray();
} catch (SubqueryNoResultException) {
}
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="' . $schemaName . '.csv";');
$handle = fopen('php://output', 'w');
$csvRow = ["id", ...array_keys($records[0]->data->toArray())];
fputcsv($handle, $csvRow, ',');
foreach ($records as $record) {
$csvRow = [$record->id, ...$record->data->toArray()];
$csvRow = array_values($csvRow);
fputcsv($handle, $csvRow, ',');
}
fclose($handle);
echo $handle;
exit;
}
public function new(Request $request)
{
$schema = $this->channelService->channel->schemas->where("name", $request->input("schema"))->first();
$recordHistory = $this->recordManager->fromSession($request->session())->getRecords();
$record = $this->recordService->createEmpty($schema, $this->authService->currentUserId());
$queryRecord = QueryRecord::fromRecord($record);
return $this->svelte->render(
layout: "channel",
view: "recordEdit",
title: "New Record",
data: [
"schema" => $schema,
"record" => $queryRecord,
"recordHistory" => $recordHistory,
"isCreateMode" => true,
]
);
}
//
//
// public function newInline(Request $request)
// {
//
// $channel = ChannelRepo::current();
// $schema = $channel->schemas->where("name.value", $request->input("schema"))->first();
// $record = Record::createEmpty($schema, AuthService::currentUserId($request));
// $queryRecord = QueryRecord::fromRecord($record);
//
// return [
// "schemas" => $channel->schemas,
// "schema" => $schema,
// "record" => $queryRecord,
// "isCreateMode" => true,
// ];
// }
public function edit(Request $request)
{
$rid = $request->route("rid");
$queryResult = $this->query
->filter(["id" => $rid])
->limit(1)
->skip(0)
->childrenDepth(2)
->childrenLimit(100)
->parentsDepth(1)
->parentsLimit(100)
->run();
$graph = $queryResult->getQueryRecords();
if (empty($graph->records[0])) {
return $this->svelte->render(
layout: "channel",
view: "recordNotFound",
title: "Record Not Found",
);
}
$record = $graph->records[0];
$schema = $this->channelService->channel->schemas->where("name", $record->_sys->schema)->first();
$recordHistory = $this->recordManager->fromSession($request->session())->push($rid)->getRecords($rid);
$users = $this->userRepo->all();
return $this->svelte->render(
layout: "channel",
view: "recordEdit",
title: "Edit Record",
data: [
"schema" => $schema,
"graph" => $graph->toArray(),
"record" => $record->toArray(),
"users" => $users,
"recordHistory" => $recordHistory,
"isCreateMode" => $record->_sys->status === "empty",
]
);
}
//
// public function editInline(Request $request)
// {
// $channel = ChannelRepo::current();
// $rid = $request->route("rid");
//
// $queryResult = $this->query
// ->filter(["id" => $rid])
// ->limit(1)
// ->childrenDepth(2)
// ->parentsDepth(1)
// ->run();
//
// $graph = $queryResult->getQueryRecords($channel->schemas);
// $record = $graph->records[0];
// return ok(
// [
// "graph" => $graph->toArray(),
// "record" => $record->toArray(),
// ]
// );
// }
//
//
// public function suggestions(Request $request)
// {
// $arguments = [
// "_sys.schema" => $request->input("schema"),
// ];
//
// if ($request->input("value")) {
// if (in_array($request->input("ui"), ["text", "date"])) {
// $arguments[$request->input("field") . "_regex"] = $request->input("value");
// } elseif ($request->input("ui") == "number") {
// $arguments[$request->input("field") . "_eqnum"] = floatval($request->input("value"));
// } elseif ($request->input("ui") == "date") {
// }
// }
//
//
// $queryResult = $this->query
// ->filter($arguments)
// ->limit(10)
// ->run();
//
// if (!$queryResult->hasResults()) {
// return ok([]);
// }
// $schemas = $this->schemaRepo->all();
// $graph = $queryResult->getQueryRecords($schemas);
//
// return ok($graph->records->toArray());
// }
//
public function save(Request $request)
{
try {
if ($request->input("isCreateMode")) {
$this->recordService->create(
schemaName: $request->input("record._sys.schema"),
data: $request->input("record.data"),
id: $request->input("record.id"),
file: $request->input("record._file") ?? [],
edges: $request->input("edges"),
status: $request->input("record._sys.status"),
uploadFromUrl: ""
);
} else {
$this->recordService->update(
id: $request->input("record.id"),
data: $request->input("record.data"),
status: $request->input("record._sys.status"),
edges: $request->input("edges"),
updateEdges: true,
);
}
$queryResult = $this->query
->filter(["id" => $request->input("record.id")])
->limit(10)
->childrenDepth(2)
->parentsDepth(1)
->run();
$newGraph = $queryResult->getQueryRecords();
} catch (ValidatorException $th) {
return fail($th->getValidatorErrors());
} catch (LucentException $th) {
return fail($th);
}
return ok($newGraph->toArray());
}
public function clone(Request $request)
{
try {
$newRecordId = $this->recordService->clone(
recordId: $request->route("rid"),
);
} catch (LucentException $th) {
return fail($th);
} catch (ValidatorException $e) {
return fail($e);
}
return ok(["id" => $newRecordId]);
}
public function status(Request $request)
{
$ids = array_map(fn($rec) => $rec["id"], $request->input("records"));
$this->recordService->changeStatusBulk(
status: $request->route("status"),
recordsIds: $ids,
);
return ok();
}
//
// public function delete(Request $request)
// {
// $ids = $request->input("ids");
//
// try {
// $this->recordService->deleteMany($ids);
// } catch (Throwable $th) {
// return fail($th);
// }
// return ok();
// }
//
// public function rollback(Request $request)
// {
// try {
// $this->recordService->rollback(
// userId: AuthService::currentUserId($request),
// recordId: $request->route("rid"),
// version: (int)$request->route("version")
// );
// } catch (ValidatorException $th) {
// return fail($th->getFirstValidatorError());
// } catch (LucentException|Throwable $th) {
// return fail($th);
// }
// return ok();
// }
}
@@ -0,0 +1,41 @@
<?php
namespace Lucent\Http\Controller;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Lucent\Account\Auth;
use Lucent\Channel\ChannelContext;
use Lucent\Record\RecordRepo;
use Lucent\Revision\RevisionRepo;
use Lucent\Schema\SchemaRepo;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
class RevisionController extends Controller
{
public function index(Request $request)
{
$revisions = RevisionRepo::getByRecordId($request->route("rid"));
return ok($revisions);
}
public function rollback(Request $request)
{
$schemas = SchemaRepo::all();
$revision = RevisionRepo::getByRecordIdAndVersion($request->route("rid"), (int)$request->route("version"));
try {
RecordRepo::replaceMany($schemas, [$revision->toDB()], Auth::currentUserId());
} catch (\Lucent\Schema\Validator\ValidatorException $th) {
return fail($th->getFirstValidatorError());
} catch (\Lucent\LucentException $th) {
return fail($th);
} catch (\Throwable $th) {
return fail($th);
}
return ok();
}
}
+126
View File
@@ -0,0 +1,126 @@
<?php
namespace Lucent\Http\Controller;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Lucent\Channel\ChannelRepo;
use Lucent\LucentException;
use Lucent\Schema\SchemaRepo;
use Lucent\Schema\SchemaService;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
use function Lucent\Svelte\svelte;
class SchemaController extends Controller
{
public function __construct(
private readonly SchemaRepo $schemaRepo,
private readonly SchemaService $schemaService
)
{
}
/**
* @throws LucentException
*/
public function new(): View
{
$schemas = $this->schemaRepo->all();
return svelte(
layout: "channel",
view: "schemaNew",
title: "Create schema",
data: [
"schemas" => $schemas,
"schema" => Schema::fromArray([]),
]
);
}
public function create(Request $request): Response
{
try {
$this->schemaService->create(
name: $request->input("name"),
label: $request->input("label"),
type: $request->input("type"),
isEntry: $request->input("isEntry"),
revisionRetentionDays: $request->input("revisionRetentionDays"),
revisionRetentionNumber: $request->input("revisionRetentionNumber"),
trashedRetentionDays: $request->input("trashedRetentionDays"),
fields: [],
path: $request->input("path"),
);
} catch (LucentException $th) {
return fail($th);
}
return ok();
}
public function edit(string $name): View
{
$channel = ChannelRepo::current();
return svelte(
layout: "channel",
view: "schemaEdit",
title: "Schemas",
data: [
"schemas" => $channel->schemas,
"schema" => $channel->schemas->where("name.value", $name)->first(),
]
);
}
public function delete(Request $request): View
{
$channel = ChannelRepo::current();
return svelte(
layout: "channel",
view: "schemaDelete",
title: "Schemas",
data: [
"channel" => $channel,
"schemas" => $channel->schemas,
"schema" => $channel->schemas->firstWhere("name", $request->route("name")),
"nav" => "collections",
]
);
}
public function update(Request $request): Response
{
try {
$schema = $this->schemaService->update(
name: $request->input("name"),
label: $request->input("label"),
isEntry: $request->input("isEntry"),
color: $request->input("color") ?? "",
visible: $request->input("visible") ?? [],
titleTemplate: $request->input("titleTemplate") ?? "",
revisionRetentionDays: $request->input("revisionRetentionDays"),
revisionRetentionNumber: $request->input("revisionRetentionNumber"),
trashedRetentionDays: $request->input("trashedRetentionDays"),
path: $request->input("path"),
);
} catch (LucentException $e) {
return fail($e);
}
return ok($schema->toArray());
}
public function postDelete(Request $request): Response
{
$this->schemaService->delete($request->input("name"));
return ok();
}
}
+66
View File
@@ -0,0 +1,66 @@
<?php
namespace Lucent\Http\Controller;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Lucent\Account\Auth;
use Lucent\Channel\ChannelContext;
use Lucent\Schema\SchemaRepo;
use Lucent\View\ViewRepo;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
class ViewController extends Controller
{
public function redirect(Request $request, string $cid, string $schemaName, string $viewName)
{
$schema = SchemaRepo::findByName($schemaName);
$view = $schema->views->whereName($viewName);
parse_str($view->params, $viewParamsArray);
return \redirect("/c/{$cid}/content/{$schemaName}/views/{$viewName}?{$view->params}");
}
public function create(Request $request)
{
try {
$schema = SchemaRepo::findByName($request->input("schemaName"));
ViewRepo::create($schema, $request->input("view"), Auth::currentUserId());
} catch (\Throwable $th) {
return fail($th);
}
return ok();
}
public function update(Request $request)
{
try {
$schema = SchemaRepo::findByName($request->input("schemaName"));
ViewRepo::update($schema, $request->input("view"));
} catch (\Throwable $th) {
return fail($th);
}
$schema = SchemaRepo::findByName($request->input("schemaName"));
$view = $schema->views->whereName($request->input("view.name"));
return ok((array)$view);
}
public function delete(Request $request, string $cid, string $schemaName, string $viewName)
{
try {
$schema = SchemaRepo::findByName($schemaName);
ViewRepo::delete($schema, $viewName);
} catch (\Throwable $th) {
return fail($th);
}
return redirect("c/{$cid}/content/{$schemaName}");
}
}