AttachmentDataTable   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 203
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 121
c 2
b 0
f 0
dl 0
loc 203
rs 10
wmc 15

4 Methods

Rating   Name   Duplication   Size   Complexity  
C configure() 0 160 10
A getQuery() 0 7 1
A __construct() 0 9 1
A buildCriteria() 0 10 3
1
<?php
2
/**
3
 * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
4
 *
5
 * Copyright (C) 2019 - 2022 Jan Böhmer (https://github.com/jbtronics)
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Affero General Public License as published
9
 * by the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License
18
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
 */
20
21
declare(strict_types=1);
22
23
namespace App\DataTables;
24
25
use App\DataTables\Column\LocaleDateTimeColumn;
26
use App\DataTables\Column\PrettyBoolColumn;
27
use App\DataTables\Column\RowClassColumn;
28
use App\DataTables\Filters\AttachmentFilter;
29
use App\Entity\Attachments\Attachment;
30
use App\Entity\LogSystem\AbstractLogEntry;
31
use App\Services\Attachments\AttachmentManager;
32
use App\Services\Attachments\AttachmentURLGenerator;
33
use App\Services\ElementTypeNameGenerator;
34
use App\Services\EntityURLGenerator;
35
use Doctrine\ORM\QueryBuilder;
36
use Omines\DataTablesBundle\Adapter\Doctrine\ORM\SearchCriteriaProvider;
37
use Omines\DataTablesBundle\Adapter\Doctrine\ORMAdapter;
38
use Omines\DataTablesBundle\Column\TextColumn;
39
use Omines\DataTablesBundle\DataTable;
40
use Omines\DataTablesBundle\DataTableTypeInterface;
41
use Symfony\Contracts\Translation\TranslatorInterface;
42
43
final class AttachmentDataTable implements DataTableTypeInterface
44
{
45
    private TranslatorInterface $translator;
46
    private EntityURLGenerator $entityURLGenerator;
47
    private AttachmentManager $attachmentHelper;
48
    private ElementTypeNameGenerator $elementTypeNameGenerator;
49
    private AttachmentURLGenerator $attachmentURLGenerator;
50
51
    public function __construct(TranslatorInterface $translator, EntityURLGenerator $entityURLGenerator,
52
                                AttachmentManager $attachmentHelper, AttachmentURLGenerator $attachmentURLGenerator,
53
                                ElementTypeNameGenerator $elementTypeNameGenerator)
54
    {
55
        $this->translator = $translator;
56
        $this->entityURLGenerator = $entityURLGenerator;
57
        $this->attachmentHelper = $attachmentHelper;
58
        $this->elementTypeNameGenerator = $elementTypeNameGenerator;
59
        $this->attachmentURLGenerator = $attachmentURLGenerator;
60
    }
61
62
    public function configure(DataTable $dataTable, array $options): void
63
    {
64
        $dataTable->add('dont_matter', RowClassColumn::class, [
65
            'render' => function ($value, Attachment $context) {
66
                //Mark attachments with missing files yellow
67
                if(!$this->attachmentHelper->isFileExisting($context)){
68
                    return 'table-warning';
69
                }
70
71
                return ''; //Default coloring otherwise
72
            },
73
        ]);
74
75
        $dataTable->add('picture', TextColumn::class, [
76
            'label' => '',
77
            'className' => 'no-colvis',
78
            'render' => function ($value, Attachment $context) {
79
                if ($context->isPicture()
80
                    && !$context->isExternal()
81
                    && $this->attachmentHelper->isFileExisting($context)) {
82
                    $title = htmlspecialchars($context->getName());
83
                    if ($context->getFilename()) {
84
                        $title .= ' ('.htmlspecialchars($context->getFilename()).')';
85
                    }
86
87
                    return sprintf(
88
                        '<img alt="%s" src="%s" data-thumbnail="%s" class="%s" data-title="%s" data-controller="elements--hoverpic">',
89
                        'Part image',
90
                        $this->attachmentURLGenerator->getThumbnailURL($context),
91
                        $this->attachmentURLGenerator->getThumbnailURL($context, 'thumbnail_md'),
92
                        'img-fluid hoverpic',
93
                        $title
94
                    );
95
                }
96
97
                return '';
98
            },
99
        ]);
100
101
        $dataTable->add('name', TextColumn::class, [
102
            'label' => 'attachment.edit.name',
103
            'render' => function ($value, Attachment $context) {
104
                //Link to external source
105
                if ($context->isExternal()) {
106
                    return sprintf(
107
                        '<a href="%s" class="link-external">%s</a>',
108
                        htmlspecialchars($context->getURL()),
0 ignored issues
show
Bug introduced by
It seems like $context->getURL() can also be of type null; however, parameter $string of htmlspecialchars() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

108
                        htmlspecialchars(/** @scrutinizer ignore-type */ $context->getURL()),
Loading history...
109
                        htmlspecialchars($value)
110
                    );
111
                }
112
113
                if ($this->attachmentHelper->isFileExisting($context)) {
114
                    return sprintf(
115
                        '<a href="%s" target="_blank" data-no-ajax>%s</a>',
116
                        $this->entityURLGenerator->viewURL($context),
117
                        htmlspecialchars($value)
118
                    );
119
                }
120
121
                return $value;
122
            },
123
        ]);
124
125
        $dataTable->add('attachment_type', TextColumn::class, [
126
            'label' => 'attachment.table.type',
127
            'field' => 'attachment_type.name',
128
            'render' => function ($value, Attachment $context) {
129
                return sprintf(
130
                    '<a href="%s">%s</a>',
131
                    $this->entityURLGenerator->editURL($context->getAttachmentType()),
132
                    htmlspecialchars($value)
133
                );
134
            },
135
        ]);
136
137
        $dataTable->add('element', TextColumn::class, [
138
            'label' => 'attachment.table.element',
139
            //'propertyPath' => 'element.name',
140
            'render' => function ($value, Attachment $context) {
141
                return sprintf(
142
                    '<a href="%s">%s</a>',
143
                    $this->entityURLGenerator->infoURL($context->getElement()),
0 ignored issues
show
Bug introduced by
It seems like $context->getElement() can also be of type null; however, parameter $entity of App\Services\EntityURLGenerator::infoURL() does only seem to accept App\Entity\Base\AbstractDBElement, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

143
                    $this->entityURLGenerator->infoURL(/** @scrutinizer ignore-type */ $context->getElement()),
Loading history...
144
                    $this->elementTypeNameGenerator->getTypeNameCombination($context->getElement(), true)
0 ignored issues
show
Bug introduced by
It seems like $context->getElement() can also be of type null; however, parameter $entity of App\Services\ElementType...etTypeNameCombination() does only seem to accept App\Entity\Contracts\NamedElementInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

144
                    $this->elementTypeNameGenerator->getTypeNameCombination(/** @scrutinizer ignore-type */ $context->getElement(), true)
Loading history...
145
                );
146
            },
147
        ]);
148
149
        $dataTable->add('filename', TextColumn::class, [
150
            'label' => $this->translator->trans('attachment.table.filename'),
151
            'propertyPath' => 'filename',
152
        ]);
153
154
        $dataTable->add('filesize', TextColumn::class, [
155
            'label' => $this->translator->trans('attachment.table.filesize'),
156
            'render' => function ($value, Attachment $context) {
157
                if ($context->isExternal()) {
158
                    return sprintf(
159
                        '<span class="badge bg-primary">
160
                        <i class="fas fa-globe fa-fw"></i>%s
161
                        </span>',
162
                        $this->translator->trans('attachment.external')
163
                    );
164
                }
165
166
                if ($this->attachmentHelper->isFileExisting($context)) {
167
                    return $this->attachmentHelper->getHumanFileSize($context);
168
                }
169
170
                return sprintf(
171
                    '<span class="badge bg-warning">
172
                        <i class="fas fa-exclamation-circle fa-fw"></i>%s
173
                        </span>',
174
                    $this->translator->trans('attachment.file_not_found')
175
                );
176
            },
177
        ]);
178
179
        $dataTable
180
            ->add('addedDate', LocaleDateTimeColumn::class, [
181
                'label' => 'part.table.addedDate',
182
                'visible' => false,
183
            ])
184
            ->add('lastModified', LocaleDateTimeColumn::class, [
185
                'label' => 'part.table.lastModified',
186
                'visible' => false,
187
            ]);
188
189
        $dataTable->add('show_in_table', PrettyBoolColumn::class, [
190
            'label' => 'attachment.edit.show_in_table',
191
            'visible' => false,
192
        ]);
193
194
        $dataTable->add('isPicture', PrettyBoolColumn::class, [
195
            'label' => 'attachment.edit.isPicture',
196
            'visible' => false,
197
            'propertyPath' => 'picture',
198
        ]);
199
200
        $dataTable->add('is3DModel', PrettyBoolColumn::class, [
201
            'label' => 'attachment.edit.is3DModel',
202
            'visible' => false,
203
            'propertyPath' => '3dmodel',
204
        ]);
205
206
        $dataTable->add('isBuiltin', PrettyBoolColumn::class, [
207
            'label' => 'attachment.edit.isBuiltin',
208
            'visible' => false,
209
            'propertyPath' => 'builtin',
210
        ]);
211
212
        $dataTable->createAdapter(ORMAdapter::class, [
213
            'entity' => Attachment::class,
214
            'query' => function (QueryBuilder $builder): void {
215
                $this->getQuery($builder);
216
            },
217
            'criteria' => [
218
                function (QueryBuilder $builder) use ($options): void {
219
                    $this->buildCriteria($builder, $options);
220
                },
221
                new SearchCriteriaProvider(),
222
            ],
223
        ]);
224
    }
225
226
    private function getQuery(QueryBuilder $builder): void
227
    {
228
        $builder->select('attachment')
229
            ->addSelect('attachment_type')
230
            //->addSelect('element')
231
            ->from(Attachment::class, 'attachment')
232
            ->leftJoin('attachment.attachment_type', 'attachment_type');
233
        //->leftJoin('attachment.element', 'element');
234
    }
235
236
    private function buildCriteria(QueryBuilder $builder, array $options): void
237
    {
238
        //We do the most stuff here in the filter class
239
        if (isset($options['filter'])) {
240
            if(!$options['filter'] instanceof AttachmentFilter) {
241
                throw new \Exception('filter must be an instance of AttachmentFilter!');
242
            }
243
244
            $filter = $options['filter'];
245
            $filter->apply($builder);
246
        }
247
248
    }
249
}
250