route("id"); $schemas = SchemaRepo::all(); $schema = collect($schemas)->firstWhere("id", $schemaId); // $users = $this->accountService->all(); $users = []; // $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, // ); // $skip = data_get($urlParams, "skip") ?? 0; $skip = 0; $limit = 30; $records = []; // $graphArray = null; // $graph = $this->query // ->filter($arguments) // ->notLinked($request->input("notlinked") ?? "") // ->limit($limit) // ->status(explode(",", $arguments["status_in"])) // ->skip($skip) // ->sort($sort) // ->childrenFields($schema?->visible ?? []) // ->childrenDepth(1) // ->parentsDepth(0) // ->runWithCount(); // $records = $graph->getRootRecords()->toArray(); $data = [ "schemas" => $schemas, "schema" => $schema, "users" => $users, "records" => $records, // "graph" => toArray($graph), // "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, // ), // "limit" => $limit, // "skip" => $skip, // "total" => $graph->total ?? 0, // "filter" => $request->input("filter") ?? [], // "inModal" => true, // "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(), // ); // } // return $data; // } // $data["inModal"] = false; return Svelte::view( 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( [ "schema" => $schema->name, "status_in" => "draft,published", ], $filter, ); $records = $this->query ->filter($arguments) ->limit(-1) ->status(explode(",", $arguments["status_in"])) ->childrenDepth(1) // ->skip($skip) ->sort($sort) ->run() ->tree(); 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, ","); foreach ($records as $record) { $csvRow = [$record->id, ...$record->data->toArray()]; $csvRow = array_merge( $csvRow, $this->makeCsvRelationColumnValues($schema, $record->_children), ); $csvRow = array_values($csvRow); fputcsv($handle, $csvRow, ","); } fclose($handle); echo $handle; 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 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 edit(Request $request) { $rid = $request->route("rid"); $graph = $this->query ->filter(["id" => $rid]) ->limit(1) ->skip(0) ->childrenDepth(2) ->childrenLimit(200) ->parentsDepth(1) ->parentsLimit(200) ->run(); if ($graph->records->isEmpty()) { return $this->svelte->render( layout: "channel", view: "recordNotFound", title: "Record Not Found", ); } $record = $graph->records->first(); if ( !in_array( $record->schema, $this->accountService->currentReadableSchemas(), ) ) { return $this->svelte->render( layout: "channel", view: "recordNotFound", title: "Schema Not Found", ); } $schema = $this->channelService->getSchema($record->schema)->get(); $recordHistory = $this->recordManager ->fromSession($request->session()) ->push($rid) ->getRecords($rid); return $this->svelte->render( layout: "channel", view: "recordEdit", title: "Edit Record", data: [ "schema" => $schema, "graph" => toArray($graph), "record" => toArray($record), "users" => $this->accountService->all(), "recordHistory" => $recordHistory, "isWritable" => in_array( $record->schema, $this->accountService->currentWritableSchemas(), ), ], ); } public function suggestions(Request $request) { $arguments = [ "schema" => $request->input("schema"), ]; if ($request->input("value")) { if (in_array($request->input("ui"), ["text", "date"])) { $arguments[ "data." . $request->input("field") . "_regex" ] = $request->input("value"); } elseif ($request->input("ui") == "number") { $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(); if ($records->isEmpty()) { return ok([]); } return ok($records->toArray()); } public function postCreate(Request $request) { $schemaId = $request->input("schemaId"); $title = $request->input("title"); $now = Carbon::now(); $userId = AuthModule::getCurrentUserId(); $titleField = new RecordField( id: "_title", locale: "main", value: $title, createdAt: $now, createdBy: $userId, updatedAt: $now, updatedBy: $userId, version: 1, ); $record = new Record( id: Id::new(), schemaId: $schemaId, draftData: [$titleField], liveData: [], createdAt: $now, createdBy: $userId, publishedAt: null, publishedBy: null, trashedAt: null, trashedBy: null, ); RecordRepo::insert($record); return ok(toArray($record)); } public function save(Request $request) { $recordId = $request->input("record.id"); try { if ($request->input("isCreateMode")) { $recordId = $this->recordService->create( data: new RecordInputData( $request->input("record.schema"), $recordId ?? "", $request->input("record.data"), Status::from($request->input("record.status")), ), 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") ?? [], ), ); } $newGraph = $this->query ->filter(["id" => $recordId]) ->limit(10) ->childrenDepth(1) ->parentsDepth(1) ->run(); } catch (ValidatorException $th) { return fail($th->getValidatorErrors()); } catch (LucentException $th) { return fail($th); } return ok(toArray($newGraph)); } 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 emptyTrash(Request $request) { $this->recordService->emptyTrash($request->route("schemaName")); return redirect( $this->channelService->channel->lucentUrl . "/content/" . $request->route("schemaName"), ); } 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( 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(); } }