Skip to content

Commit 28cd5d7

Browse files
committed
[WIP] Display links to files
Related to #17
1 parent a039de3 commit 28cd5d7

File tree

5 files changed

+145
-19
lines changed

5 files changed

+145
-19
lines changed

config/autoload/templates.global.php

+2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
return [
66
'dependencies' => [
77
'factories' => [
8+
App\Twig\FileExtension::class => Zend\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory::class,
89
App\Twig\ValueExtension::class => Zend\ServiceManager\AbstractFactory\ReflectionBasedAbstractFactory::class,
910
],
1011
],
1112
'twig' => [
1213
'extensions' => [
14+
App\Twig\FileExtension::class,
1315
App\Twig\ValueExtension::class,
1416
],
1517
],

src/App/Twig/FileExtension.php

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Twig;
6+
7+
use Twig\Extension\AbstractExtension;
8+
use Twig\TwigFunction;
9+
10+
class FileExtension extends AbstractExtension
11+
{
12+
public function getFunctions(): array
13+
{
14+
return [
15+
new TwigFunction('file', [$this, 'file'], ['is_safe' => ['html']]),
16+
];
17+
}
18+
19+
public function file($path, bool $preview, bool $download): string
20+
{
21+
if (!is_null($path)) {
22+
$path = trim($path);
23+
}
24+
25+
if (is_null($path) || strlen($path) === 0 || !file_exists($path)) {
26+
$output = '<td';
27+
$output .= ' class="text-nowrap"';
28+
$output .= ' colspan="2"';
29+
$output .= '>';
30+
31+
if (is_null($path)) {
32+
$output .= ValueExtension::null();
33+
} elseif (strlen($path) === 0) {
34+
$output .= '';
35+
} elseif (!file_exists($path)) {
36+
$output .= self::notexists($path);
37+
}
38+
39+
$output .= '</td>';
40+
} else {
41+
$output = '';
42+
43+
if ($preview === true) {
44+
$output = '<td ';
45+
$output .= ' class="text-nowrap"';
46+
$output .= $download !== true ? ' colspan="2"' : '';
47+
$output .= '>';
48+
$output .= self::preview($path, true);
49+
$output .= '</td>';
50+
}
51+
52+
if ($download === true) {
53+
$output .= '<td ';
54+
$output .= ' class="text-nowrap"';
55+
$output .= $preview !== true ? ' colspan="2"' : '';
56+
$output .= '>';
57+
$output .= self::download($path, $preview && $download ? false : true);
58+
$output .= '</td>';
59+
}
60+
}
61+
62+
return $output;
63+
}
64+
65+
private function notexists($path) : string
66+
{
67+
return '<span class="text-muted" title="File does not exists." style="cursor: help; font-style: italic;">'
68+
.'<i class="fas fa-fw fa-exclamation-circle"></i>'
69+
.' '.basename($path)
70+
.'</span>';
71+
}
72+
73+
private function preview($path, bool $displayFilename) : string
74+
{
75+
return '<a href="#" style="text-decoration: none;">'
76+
.'<i class="far fa-fw fa-eye"></i> '
77+
.($displayFilename ? ' '.basename($path) : '')
78+
.'</a>';
79+
}
80+
81+
private function download($path, bool $displayFilename) : string
82+
{
83+
return '<a href="#" style="text-decoration: none;">'
84+
.'<i class="fas fa-fw fa-file-download"></i> '
85+
.($displayFilename ? ' '.basename($path) : '')
86+
.'</a>';
87+
}
88+
}

src/App/Twig/ValueExtension.php

+21-9
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,34 @@ public function getFunctions(): array
1818

1919
public function value($value, ?string $datatype = null): string
2020
{
21-
if (is_null($value)) {
22-
return self::null();
21+
$textAlign = 'left';
22+
if ($datatype === 'integer') {
23+
$textAlign = 'right';
24+
} elseif ($datatype === 'boolean') {
25+
$textAlign = 'center';
2326
}
2427

25-
if ($datatype === 'boolean') {
26-
return self::boolean($value);
27-
}
28+
$output = '<td';
29+
$output .= sprintf(' class="text-nowrap text-%s"', $textAlign);
30+
$output .= sprintf(' data-datatype="%s"', (string) $datatype);
31+
$output .= '>';
2832

29-
if (is_string($value) && filter_var($value, FILTER_VALIDATE_URL) !== false) {
30-
return self::varcharLink($value);
33+
if (is_null($value)) {
34+
$output .= self::null();
35+
} elseif ($datatype === 'boolean') {
36+
$output .= self::boolean($value);
37+
} elseif (is_string($value) && filter_var($value, FILTER_VALIDATE_URL) !== false) {
38+
$output .= self::varcharLink($value);
39+
} else {
40+
$output .= (string) $value;
3141
}
3242

33-
return (string) $value;
43+
$output .= '</td>';
44+
45+
return $output;
3446
}
3547

36-
private static function null(): string
48+
public static function null(): string
3749
{
3850
return '<span class="text-muted font-italic">NULL</span>';
3951
}

templates/app/table/body.html.twig

+14-8
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@
1616
</td>
1717
{% endif %}
1818

19-
<td class="text-nowrap{{ column.datatype == 'integer' ? ' text-right' : column.datatype == 'boolean' ? ' text-center' }}"
20-
data-datatype="{{ column.datatype }}">
21-
{{ value(value, column.datatype) }}
22-
</td>
19+
{% if column.config.preview == true or column.config.download == true %}
20+
{{ file(value, column.config.preview, column.config.download) }}
21+
{% else %}
22+
{{ value(value, column.datatype) }}
23+
{% endif %}
2324

2425
{% endfor %}
2526

@@ -29,10 +30,15 @@
2930
{% set fcolumns = foreign.columns | filter(c => c.name in fselectColumns) %}
3031

3132
{% for fcolumn in fcolumns %}
32-
<td
33-
class="table-info text-nowrap{{ fcolumn.datatype == 'integer' ? ' text-right' : fcolumn.datatype == 'boolean' ? ' text-center' }}">
34-
{{ value(attribute(record.properties, foreign.name ~ '.' ~ fcolumn.name), fcolumn.datatype) }}
35-
</td>
33+
34+
{% set value = attribute(record.properties, foreign.name ~ '.' ~ fcolumn.name) %}
35+
36+
{% if fcolumn.config.preview == true or fcolumn.config.download == true %}
37+
{{ file(value, fcolumn.config.preview, fcolumn.config.download) }}
38+
{% else %}
39+
{{ value(value, fcolumn.datatype) }}
40+
{% endif %}
41+
3642
{% endfor %}
3743

3844
{% endfor %}

templates/app/table/head.html.twig

+20-2
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,23 @@
1111
</tr>
1212
<tr>
1313
{% for column in columns %}
14+
1415
{% set columnName = table.name ~ '.' ~ column.name %}
15-
<th scope="col" {{ thematic.column == column.name ? ' colspan="2"'}}>
16+
17+
{% set colspan = 1 %}
18+
{% if thematic.column == column.name %}
19+
{% set colspan = 2 %}
20+
{% elseif column.config.preview == true or column.config.download == true %}
21+
{% set colspan = 2 %}
22+
{% endif %}
23+
24+
<th scope="col" colspan="{{ colspan }}">
1625
<a href="{{ path('table', {'config': configId, 'offset': 0}) }}?sort={{ columnName }}&amp;order={{ sort == columnName and order == 'asc' ? 'desc' : 'asc' }}"
1726
class="d-flex justify-content-between align-items-center">
1827
<span class="text-nowrap">
1928
{{ thematic.column == column.name ? '<i class="fas fa-palette"></i>' }}
2029
{{ column.isForeignKey == true ? '<i class="fas fa-link"></i>' }}
30+
{{ column.config.preview == true or column.config.download == true ? '<i class="fas fa-file"></i>' }}
2131
{{ column.name }}
2232
</span>
2333
{% if sort == columnName and order == 'asc' %}
@@ -37,11 +47,18 @@
3747
{% set fcolumns = foreign.columns | filter(c => c.name in fselectColumns) %}
3848

3949
{% for fcolumn in fcolumns %}
40-
<th scope="col">
50+
51+
{% set colspan = 1 %}
52+
{% if fcolumn.config.preview == true or fcolumn.config.download == true %}
53+
{% set colspan = 2 %}
54+
{% endif %}
55+
56+
<th scope="col" colspan="{{ colspan }}">
4157
{% set columnName = foreign.name ~ '.' ~ fcolumn.name %}
4258
<a href="{{ path('table', {'config': configId, 'offset': 0}) }}?sort={{ columnName }}&amp;order={{ sort == columnName and order == 'asc' ? 'desc' : 'asc' }}"
4359
class="d-flex justify-content-between align-items-center">
4460
<span class="text-nowrap">
61+
{{ fcolumn.config.preview == true or fcolumn.config.download == true ? '<i class="fas fa-file"></i>' }}
4562
{{ fcolumn.name }}
4663
</span>
4764
{% if sort == columnName and order == 'asc' %}
@@ -53,6 +70,7 @@
5370
{% endif %}
5471
</a>
5572
</th>
73+
5674
{% endfor %}
5775

5876
{% endfor %}

0 commit comments

Comments
 (0)