Files
lucent-laravel/src/Record/RecordService.php
T

272 lines
7.7 KiB
PHP
Raw Normal View History

2023-10-02 23:10:49 +03:00
<?php
namespace Lucent\Record;
use Illuminate\Support\Str;
use Lucent\Account\AuthService;
use Lucent\Channel\ChannelService;
use Lucent\Edge\Edge;
use Lucent\Edge\EdgeCollection;
use Lucent\Edge\EdgeRepo;
use Lucent\File\FileService;
use Lucent\Id\Id;
use Lucent\LucentException;
use Lucent\Query\Query;
use Lucent\Revision\RevisionService;
use Lucent\Schema\FieldInterface;
use Lucent\Schema\Schema;
use Lucent\Schema\Validator\Validator;
use Lucent\Schema\Validator\ValidatorException;
readonly class RecordService
{
public function __construct(
private AuthService $authService,
private RevisionService $revisionService,
private ChannelService $channelService,
private Validator $recordValidator,
private Query $query,
2023-10-06 18:47:50 +03:00
private InputFormatter $inputFormatter,
private RecordRepo $recordRepo
2023-10-02 23:10:49 +03:00
)
{
}
/**
* @throws LucentException
* @throws ValidatorException
*/
public
function create(
string $schemaName,
array $data,
?string $id = null,
array $file = [],
array $edges = [],
string $status = "draft",
string $uploadFromUrl = "",
): string
{
2023-10-17 18:30:41 +03:00
$schema = $this->channelService->getSchema($schemaName)->get();
2023-10-02 23:10:49 +03:00
$formattedData = $this->inputFormatter->fill($schemaName, new RecordData($data));
if (empty($formattedData["id"])) {
$formattedData["id"] = Id::new();
}
$uploadResult = FileService::create($schema, $uploadFromUrl, $file);
$uniqueEdges = collect($edges)
->map(function ($edge, $index) {
2023-10-04 13:32:30 +03:00
$edge["rank"] = $index;
return (array)(new Edge(...$edge));
2023-10-02 23:10:49 +03:00
})
->unique(fn($e) => $e['field'] . $e['source'] . $e['target'] . $e['sourceSchema'])
->values()->toArray();
$uniqueEdgesCollection = EdgeCollection::fromArray($uniqueEdges);
if ($uploadResult->isDuplicate) {
EdgeRepo::update($uploadResult->duplicateId, $uniqueEdgesCollection);
return $uploadResult->duplicateId;
}
$record = new Record(
2023-10-07 21:18:18 +03:00
id: empty($id) ? Id::new() : $id,
2023-10-04 13:32:30 +03:00
schema: $schema->name,
status: Status::from($status),
_sys: System::newRecord($this->authService->currentUserId()),
2023-10-02 23:10:49 +03:00
data: $formattedData,
_file: $uploadResult->recordFile,
);
2023-10-13 21:06:23 +03:00
if (Status::from($status) === Status::PUBLISHED) {
$errors = $this->recordValidator->check($schemaName, $record->data, $uniqueEdgesCollection);
if ($errors->isNotEmpty()) {
$this->recordValidator->throwException($errors);
}
2023-10-02 23:10:49 +03:00
}
RecordRepo::create($record);
EdgeRepo::update($record->id, $uniqueEdgesCollection);
2023-10-15 19:14:07 +03:00
$this->revisionService->create($record,$uniqueEdgesCollection);
2023-10-02 23:10:49 +03:00
return $record->id;
}
/**
* @throws LucentException
* @throws ValidatorException
*/
2023-11-21 14:06:41 +02:00
public function update(
2023-10-02 23:10:49 +03:00
string $id,
array $data,
string $status = "draft",
array $edges = [],
bool $updateEdges = false
): void
{
2023-10-04 13:32:30 +03:00
$record = $this->query->filter(["id" => $id])->run()->records->first();
2023-10-02 23:10:49 +03:00
if (empty($record)) {
throw new LucentException("Record id is missing");
}
2023-10-04 13:32:30 +03:00
$formattedData = $this->inputFormatter->fill($record->schema, new RecordData($data));
2023-10-02 23:10:49 +03:00
2023-10-15 19:14:07 +03:00
$uniqueEdgesCollection = new EdgeCollection();
2023-10-02 23:10:49 +03:00
if ($updateEdges) {
$uniqueEdges = collect($edges)
->map(function ($edge, $index) {
2023-10-04 13:32:30 +03:00
$edge["rank"] = $index;
2023-10-02 23:10:49 +03:00
$edgeData = (array)(new Edge(...$edge));
return $edgeData;
})
->unique(fn($e) => $e['field'] . $e['source'] . $e['target'] . $e['sourceSchema'])
->values()->toArray();
$uniqueEdgesCollection = EdgeCollection::fromArray($uniqueEdges);
2023-10-13 21:06:23 +03:00
}
if (Status::from($status) === Status::PUBLISHED) {
2023-11-21 14:06:41 +02:00
$errors = $this->recordValidator->check($record->schema, $formattedData, $uniqueEdgesCollection);
2023-10-13 21:06:23 +03:00
if ($errors->isNotEmpty()) {
$this->recordValidator->throwException($errors);
}
if ($errors->isNotEmpty()) {
$this->recordValidator->throwException($errors);
}
2023-10-02 23:10:49 +03:00
}
$newRecord = new Record(
id: $record->id,
2023-10-04 13:32:30 +03:00
schema: $record->schema,
status: Status::from($status),
_sys: $record->_sys->update($this->authService->currentUserId()),
2023-10-02 23:10:49 +03:00
data: $record->data->merge($formattedData),
_file: $record->_file,
);
RecordRepo::update($newRecord);
if ($updateEdges) {
EdgeRepo::update($newRecord->id, $uniqueEdgesCollection);
}
2023-10-15 19:14:07 +03:00
$this->revisionService->create($newRecord,$uniqueEdgesCollection);
2023-10-02 23:10:49 +03:00
}
/**
*/
2023-11-21 14:06:41 +02:00
public function changeStatusBulk(
2023-10-02 23:10:49 +03:00
string $status,
array $recordsIds,
): void
{
2023-10-04 13:32:30 +03:00
RecordRepo::updateStatusBulk(Status::from($status), $recordsIds);
2023-10-02 23:10:49 +03:00
}
/**
* @throws LucentException
* @throws ValidatorException
*/
public
function clone(
string $recordId,
): string
{
2023-10-04 13:32:30 +03:00
$graph = $this->query
2023-10-02 23:10:49 +03:00
->filter(["id" => $recordId])
->limit(1)
->childrenDepth(1)
2023-10-04 13:32:30 +03:00
->run();
2023-10-02 23:10:49 +03:00
2023-10-04 13:32:30 +03:00
$record = $graph->records->first();
2023-10-02 23:10:49 +03:00
if (empty($record)) {
throw new LucentException("Record id is missing");
}
2023-10-04 13:32:30 +03:00
2023-10-02 23:10:49 +03:00
$newRecordId = (string)Str::uuid();
$newEdgesData = $graph->edges
->filter(fn(Edge $edge) => $edge->source == $recordId)
->values()
->map(function (Edge $edge) use ($newRecordId) {
$edge->source = $newRecordId;
return $edge->toArray();
})->toArray();
$record->id = $newRecordId;
return $this->create(
2023-10-04 13:32:30 +03:00
schemaName: $record->schema,
2023-10-02 23:10:49 +03:00
data: $record->data->toArray(),
id: $record->id,
file: $record->_file?->toArray() ?? [],
edges: $newEdgesData,
status: "draft"
);
}
public function deleteMany(
array $recordsIds,
): void
{
2023-10-06 18:47:50 +03:00
$this->recordRepo->deleteMany($recordsIds);
2023-10-02 23:10:49 +03:00
}
2023-10-15 23:40:34 +03:00
public function emptyTrash(
string $schemaName,
): void
{
$schema = $this->channelService->getSchema($schemaName)->get();
$this->recordRepo->deleteTrashedBySchema($schemaName);
}
2023-10-02 23:10:49 +03:00
/**
* @throws LucentException
* @throws ValidatorException
*/
public function rollback(
string $recordId,
int $version,
): void
{
$revision = $this->revisionService->getByRecordIdAndVersion($recordId, $version)->get();
$this->update(
id: $revision->recordId,
data: $revision->data->toArray(),
2023-10-15 19:14:07 +03:00
edges: toArray($revision->_edges),
updateEdges: true
2023-10-02 23:10:49 +03:00
);
}
public function createEmpty(
Schema $schema,
): Record
{
$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));
return new Record(
id: Id::new(),
2023-10-04 13:32:30 +03:00
schema: $schema->name,
status: Status::DRAFT,
2023-10-13 21:06:23 +03:00
_sys: System::newRecord($this->authService->currentUserId()),
2023-10-02 23:10:49 +03:00
data: $formattedData,
_file: null,
);
}
}