datatable.directory codebase https://datatable.directory/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
datatable.directory/app/Http/Controllers/TableController.php

147 lines
4.7 KiB

<?php
namespace App\Http\Controllers;
use App\Models\Revision;
use App\Models\Row;
use App\Models\Table;
use App\Models\User;
use App\Utils\Column;
use Illuminate\Http\Request;
use MightyPork\Exceptions\NotApplicableException;
class TableController extends Controller
{
public function view(User $user, string $table)
{
/** @var Table $tableModel */
$tableModel = $user->tables()->where('name', $table)->first();
$revision = $tableModel->activeRevision;
return view('table.view', [
'table' => $tableModel,
'revision' => $revision,
'columns' => Column::columnsFromJson(json_decode($revision->columns)),
'rows' => $revision->rows,
]);
}
/**
* SHow a form for creating a new table
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$exampleColumns =
"latin,string,Latin Name\n" .
"common,string,Common Name\n" .
"lifespan,int,Lifespan (years)";
$exampleData =
"Mercenaria mercenaria,hard clam,40\n" .
"Magallana gigas,pacific oyster,30\n" .
"Patella vulgata,common limpet,20";
return view('table.create',
compact('exampleColumns', 'exampleData')
);
}
public function storeNew(Request $request)
{
/** @var User $u */
$u = \Auth::user();
$this->validate($request, [
'name' => 'required',
'title' => 'string',
'description' => 'string|nullable',
'license' => 'string|nullable',
'origin' => 'string|nullable',
'columns' => 'required',
'data' => 'string|nullable',
]);
// Check if table name is unique for user
$tabName = $request->get('name');
if ($u->tables()->where('name', $tabName)->exists()) {
return $this->backWithErrors([
'name' => "A table called \"$tabName\" already exists in your account.",
]);
}
// Parse and validate the columns specification
/** @var Column[] $columns */
$columns = [];
$colTable = array_map('str_getcsv', explode("\n", $request->get('columns')));
foreach ($colTable as $col) {
$col = array_map('trim', $col);
if (count($col) < 2) {
return $this->backWithErrors([
'columns' => "All columns must have at least name and type.",
]);
}
try {
$columns[] = new Column([
'name' => $col[0],
'type' => $col[1],
'title' => count($col) >= 3 ? $col[2] : $col[0], // title falls back to =name if not specified,
]);
} catch (\Exception $e) {
return $this->backWithErrors(['columns' => $e->getMessage()]);
}
}
$rowTable = array_map('str_getcsv', explode("\n", $request->get('data')));
// Preparing data to insert into the Rows table
$rowsData = null;
try {
$rowsData = array_map(function ($row) use ($columns) {
if (count($row) != count($columns)) {
throw new NotApplicableException("All rows must have " . count($columns) . " fields.");
}
$parsed = [];
foreach ($row as $i => $val) {
$key = $columns[$i]->name;
$parsed[$key] = $columns[$i]->cast($val);
}
return [
'data' => json_encode($parsed),
'refs' => 1,
];
}, $rowTable);
} catch (\Exception $e) {
return $this->backWithErrors(['columns' => $e->getMessage()]);
}
$revision = Revision::create([
'refs' => 1, // from the new table
'note' => "Initial revision of table $u->name/$tabName",
'columns' => json_encode($columns),
]);
$table = Table::create([
'owner_id' => $u->id,
'revision_id' => $revision->id,
'name' => $tabName,
'title' => $request->get('title'),
'description' => $request->get('description'),
'license' => $request->get('license'),
'origin' => $request->get('origin'),
]);
// Attach the revision to the table, set as current
$table->revisions()->attach($revision);
$table->activeRevision()->associate($revision);
// Spawn the rows, linked to the revision
$revision->rows()->createMany($rowsData);
// Now we create rows, a revision pointing to them, and the table using it.
return "Ok.";
}
}