Skip to content

Commit 588ec69

Browse files
committed
Update DataTables helper to use controller
1 parent 0c44332 commit 588ec69

8 files changed

Lines changed: 143 additions & 62 deletions

File tree

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
"ext-simplexml": "*",
2929
"ext-xsl": "*",
3030
"ext-zip": "*",
31-
"api-platform/laravel": "^4.1",
31+
"api-platform/laravel": "^4.2.14",
32+
"cuyz/valinor": "^2.3",
3233
"davidepastore/codice-fiscale": "^0.10.0",
3334
"devcode-it/ical-easy-reader": "dev-main",
3435
"devcode-it/sdd_ita": "dev-master",
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace API\Controllers;
4+
5+
use ApiPlatform\Metadata\Operation;
6+
use ApiPlatform\Metadata\Post;
7+
use ApiPlatform\State\ProcessorInterface;
8+
use DTO\DataTablesLoadRequest\Column;
9+
use DTO\DataTablesLoadRequest\DataTablesLoadRequest;
10+
use DTO\DataTablesLoadResponse\DataTablesLoadResponse;
11+
use Models\Module;
12+
use Util\Query;
13+
14+
use Illuminate\Http\JsonResponse;
15+
use Illuminate\Http\Request;
16+
use Illuminate\Routing\Controller;
17+
18+
use Exception;
19+
20+
class InvalidInputException extends Exception {
21+
public function __construct(\CuyZ\Valinor\Mapper\MappingError $error) {
22+
$messages = $error->messages();
23+
24+
$formatted = [];
25+
foreach ($messages as $message) {
26+
$formatted[] = str_replace(". for", " for", $message->withBody('{original_message} for parameter "{node_path}"')->toString());
27+
}
28+
29+
parent::__construct("Invalid input: ".implode("\n", $formatted));
30+
}
31+
}
32+
33+
abstract class BaseController extends Controller
34+
{
35+
/**
36+
* @template T
37+
* @param class-string<T> $class_reference
38+
* @return T
39+
*/
40+
public function _cast(Request $request, string $class_reference): mixed
41+
{
42+
try {
43+
return (new \CuyZ\Valinor\MapperBuilder())
44+
->allowUndefinedValues()
45+
->allowSuperfluousKeys()
46+
->allowScalarValueCasting()
47+
->mapper()
48+
->map(
49+
$class_reference,
50+
[...$request->route()->parameters(), ...$request->all()]
51+
);
52+
} catch (\CuyZ\Valinor\Mapper\MappingError $error) {
53+
throw new InvalidInputException($error);
54+
}
55+
}
56+
}

src/API/Controllers/DataTablesController.php

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,49 @@
1111
use Models\Module;
1212
use Util\Query;
1313

14+
use Illuminate\Http\JsonResponse;
15+
use Illuminate\Http\Request;
16+
use Illuminate\Routing\Controller;
17+
18+
1419
#[Post(
1520
uriTemplate: '/datatables/list/{id_module}/{id_plugin}/{id_parent}',
16-
processor: DataTablesController::class,
21+
controller: DataTablesController::class,
1722
input: DataTablesLoadRequest::class,
1823
output: DataTablesLoadResponse::class,
1924
)]
2025
class DataTablesResource
2126
{
2227
}
2328

24-
final class DataTablesController implements ProcessorInterface
29+
final class DataTablesController extends BaseController
2530
{
26-
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): DataTablesLoadResponse
31+
public function __invoke(Request $request): JsonResponse
2732
{
28-
if (!$data instanceof DataTablesLoadRequest) {
33+
$request_body = $this->_cast($request, DataTablesLoadRequest::class);
34+
35+
$id_module = (int) $request_body->getIdModule();
36+
$id_plugin = (int) $request_body->getIdPlugin();
37+
$id_parent = (int) $request_body->getIdParent();
38+
39+
$module = \Modules::get($id_module);
40+
\Modules::setCurrent($id_module);
41+
42+
$plugin = null;
43+
if (!empty($id_plugin)) {
44+
\Plugins::setCurrent($id_plugin);
45+
$plugin = \Plugins::get($id_plugin);
46+
}
47+
48+
$structure = $plugin ?? $module;
49+
50+
return new JsonResponse($this->retrieveRecords($structure, $request_body, $id_module, $id_plugin, $id_parent));
51+
}
52+
53+
/*
54+
public function process(mixed $request, Operation $operation, array $uriVariables = [], array $context = []): DataTablesLoadResponse
55+
{
56+
if (!$request instanceof DataTablesLoadRequest) {
2957
throw new \InvalidArgumentException();
3058
}
3159
@@ -44,21 +72,23 @@ public function process(mixed $data, Operation $operation, array $uriVariables =
4472
4573
$structure = $plugin ?? $module;
4674
47-
return $this->retrieveRecords($structure, $data, $id_module, $id_plugin, $id_parent);
48-
}
75+
return $this->retrieveRecords($structure, $request, $id_module, $id_plugin, $id_parent);
76+
}*/
4977

50-
private function retrieveRecords($structure, DataTablesLoadRequest $data, $id_module, $id_plugin, $id_parent): DataTablesLoadResponse
78+
private function retrieveRecords($structure, DataTablesLoadRequest $request, $id_module, $id_plugin, $id_parent): DataTablesLoadResponse
5179
{
5280
// Informazioni fondamentali
53-
$order = $data->order ? $data->order[0] : [];
81+
$order = $request->order ? $request->order[0] : [];
5482

5583
if (!empty($order)) {
56-
$order['column'] = $order['column'] - 1;
84+
$order->column = $order->column - 1;
5785
}
5886

87+
$order_array = $order->toArray();
88+
5989
$query_structure = Query::readQuery($structure);
6090

61-
$response = new DataTablesLoadResponse($data->draw);
91+
$response = new DataTablesLoadResponse($request->draw);
6292

6393
$query = Query::getQuery($structure, [], [], [], $query_structure);
6494
if (empty($query)) {
@@ -67,7 +97,7 @@ private function retrieveRecords($structure, DataTablesLoadRequest $data, $id_mo
6797

6898
// Ricerca
6999
$search = [];
70-
$columns = $data->columns;
100+
$columns = $request->columns;
71101
array_shift($columns);
72102
for ($i = 0; $i < count($columns); ++$i) {
73103
$col = Column::fromArray($columns[$i]);
@@ -80,7 +110,7 @@ private function retrieveRecords($structure, DataTablesLoadRequest $data, $id_mo
80110
$response->recordsTotal = database()->fetchNum($query);
81111

82112
// CONTEGGIO RECORD FILTRATI (senza LIMIT)
83-
$query_filtered = Query::getQuery($structure, $search, $order, [], $query_structure);
113+
$query_filtered = Query::getQuery($structure, $search, $order_array, [], $query_structure);
84114
if (empty($id_plugin)) {
85115
$query_filtered = \Modules::replaceAdditionals($id_module, $query_filtered);
86116
}
@@ -93,11 +123,11 @@ private function retrieveRecords($structure, DataTablesLoadRequest $data, $id_mo
93123
$response->avg = Query::getAverages($structure, $search);
94124

95125
$limit = [
96-
'start' => $data->start,
97-
'length' => $data->length,
126+
'start' => $request->start,
127+
'length' => $request->length,
98128
];
99129
// RISULTATI VISIBILI (con LIMIT)
100-
$query = Query::getQuery($structure, $search, $order, $limit, $query_structure);
130+
$query = Query::getQuery($structure, $search, $order_array, $limit, $query_structure);
101131

102132
// Filtri derivanti dai permessi (eventuali)
103133
if (empty($id_plugin)) {
@@ -154,17 +184,17 @@ private function getSingleRow($r, $query_structure, $align, $id_module, $id_plug
154184

155185
$result = [
156186
'id' => $r['id'],
157-
'<span class="hide" data-id="'.$r['id'].'"></span>', // Colonna ID
187+
'<span class="hide" request-id="'.$r['id'].'"></span>', // Colonna ID
158188
];
159189

160190
foreach ($query_structure['fields'] as $pos => $field) {
161191
$column = [];
162192

163193
if (!empty($r['_bg_'])) {
164194
if (preg_match('/-light$/', (string) $r['_bg_'])) {
165-
$column['data-background'] = substr((string) $r['_bg_'], 0, -6); // Remove the "-light" suffix from the word
195+
$column['request-background'] = substr((string) $r['_bg_'], 0, -6); // Remove the "-light" suffix from the word
166196
} else {
167-
$column['data-background'] = $r['_bg_'];
197+
$column['request-background'] = $r['_bg_'];
168198
}
169199
}
170200

@@ -211,7 +241,7 @@ private function getSingleRow($r, $query_structure, $align, $id_module, $id_plug
211241
}
212242

213243
$column['class'] = 'text-center small';
214-
$column['data-background'] = $r[$field];
244+
$column['request-background'] = $r[$field];
215245
}
216246

217247
// Icona di stampa
@@ -245,8 +275,8 @@ private function getSingleRow($r, $query_structure, $align, $id_module, $id_plug
245275
}
246276

247277
// Colore del testo
248-
if (!empty($column['data-background'])) {
249-
$column['data-color'] ??= color_inverse(trim((string) $column['data-background']));
278+
if (!empty($column['request-background'])) {
279+
$column['request-color'] ??= color_inverse(trim((string) $column['request-background']));
250280
} elseif (preg_match('/^mailto_(.+?)$/', trim((string) $field), $m)) {
251281
$column['class'] = '';
252282
$value = ($r[$field] ? '<a class="btn btn-default btn-sm btn-block" style="font-weight:normal;" href="mailto:'.$r[$field].'" target="_blank"><i class="fa fa-envelope text-primary"></i> '.$r[$field].'</a>' : '');
@@ -269,13 +299,13 @@ private function getSingleRow($r, $query_structure, $align, $id_module, $id_plug
269299

270300
// Link per i moduli
271301
if (empty($id_plugin)) {
272-
$column['data-link'] = base_path_osm().'/editor.php?id_module='.$id_module.'&id_record='.$id_record.$hash;
302+
$column['request-link'] = base_path_osm().'/editor.php?id_module='.$id_module.'&id_record='.$id_record.$hash;
273303
}
274304
// Link per i plugin
275305
else {
276-
$column['data-link'] = base_path_osm().'/add.php?id_module='.$id_module.'&id_record='.$id_record.'&id_plugin='.$id_plugin.'&id_parent='.$id_parent.'&edit=1'.$hash;
306+
$column['request-link'] = base_path_osm().'/add.php?id_module='.$id_module.'&id_record='.$id_record.'&id_plugin='.$id_plugin.'&id_parent='.$id_parent.'&edit=1'.$hash;
277307

278-
$column['data-type'] = 'dialog';
308+
$column['request-type'] = 'dialog';
279309
}
280310
}
281311

src/DTO/DataTablesLoadRequest/Column.php

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,6 @@ public function __construct(
1515
) {
1616
}
1717

18-
public static function fromArray(array $input = []): self
19-
{
20-
$data = isset($input['data']) ? (string) $input['data'] : '';
21-
$name = isset($input['name']) ? (string) $input['name'] : null;
22-
$searchable = isset($input['searchable']) ? filter_var($input['searchable'], FILTER_VALIDATE_BOOLEAN) : true;
23-
$orderable = isset($input['orderable']) ? filter_var($input['orderable'], FILTER_VALIDATE_BOOLEAN) : true;
24-
$search = isset($input['search']) && is_array($input['search'])
25-
? Search::fromArray($input['search'])
26-
: null;
27-
28-
return new self($data, $name, $searchable, $orderable, $search);
29-
}
30-
3118
public function getData(): string
3219
{
3320
return $this->data;

src/DTO/DataTablesLoadRequest/DataTablesLoadRequest.php

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,49 @@
44

55
namespace DTO\DataTablesLoadRequest;
66

7+
use Symfony\Component\Serializer\Attribute\Ignore;
8+
79
final class DataTablesLoadRequest
810
{
11+
// Private properties are from the route
12+
// We must use Ignore on the getters to prevent them from being serialized
13+
private ?int $id_module = 0;
14+
private ?int $id_plugin = 0;
15+
private ?int $id_parent = 0;
16+
917
public int $draw = 0;
1018
public int $start = 0;
1119
public int $length = 200;
12-
/**
13-
* @var Search
14-
*/
15-
public array $search; // Deserialization is not working correctly
20+
21+
public Search $search;
1622
/**
1723
* @var OrderItem[]
1824
*/
19-
public array $order = []; // Deserialization is not working correctly
25+
public array $order = [];
2026
/**
2127
* @var Column[]
2228
*/
23-
public array $columns = []; // Deserialization is not working correctly
29+
public array $columns = [];
2430
public ?string $_ = null;
2531

32+
#[Ignore]
33+
public function getIdModule(): int
34+
{
35+
return $this->id_module;
36+
}
37+
38+
#[Ignore]
39+
public function getIdPlugin(): int
40+
{
41+
return $this->id_plugin;
42+
}
43+
44+
#[Ignore]
45+
public function getIdParent(): int
46+
{
47+
return $this->id_parent;
48+
}
49+
2650
public function getDraw(): int
2751
{
2852
return $this->draw;

src/DTO/DataTablesLoadRequest/OrderItem.php

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,6 @@ public function __construct(public int $column = 0, public ?string $name = null,
1414
{
1515
}
1616

17-
public static function fromArray(array $input = []): self
18-
{
19-
$col = isset($input['column']) ? (int) $input['column'] : 0;
20-
$name = isset($input['name']) && $input['name'] !== '' ? (string) $input['name'] : null;
21-
$dirStr = isset($input['dir']) ? (string) $input['dir'] : SortDirection::ASC->value;
22-
23-
return new self($col, $name, SortDirection::from($dirStr));
24-
}
25-
2617
public function getColumnIndex(): int
2718
{
2819
return $this->column;

src/DTO/DataTablesLoadRequest/Search.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,6 @@ public function __construct(public string $value, public bool $regex = false)
1010
{
1111
}
1212

13-
public static function fromArray(array $input = []): self
14-
{
15-
$value = isset($input['value']) ? (string) $input['value'] : '';
16-
$regex = isset($input['regex']) ? filter_var($input['regex'], FILTER_VALIDATE_BOOLEAN) : false;
17-
18-
return new self($value, $regex);
19-
}
20-
2113
public function getValue(): string
2214
{
2315
return $this->value;

src/DTO/DataTablesLoadResponse/DataTablesLoadResponse.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function toArray(): array
3131
'data' => $this->data,
3232
'summable' => $this->summable,
3333
'avg' => $this->avg,
34-
'error' => $this->error,
34+
$this->error ? ['error' => $this->error] : [],
3535
];
3636
}
3737
}

0 commit comments

Comments
 (0)