Completed
Pull Request — 5.6 (#2830)
by Jeroen
14:14
created

AdminList/TranslationAdminListConfigurator.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\TranslatorBundle\AdminList;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\Query\QueryBuilder;
7
use Kunstmaan\AdminListBundle\AdminList\Configurator\AbstractDoctrineDBALAdminListConfigurator;
8
use Kunstmaan\AdminListBundle\AdminList\Configurator\ChangeableLimitInterface;
9
use Kunstmaan\AdminListBundle\AdminList\Field;
10
use Kunstmaan\AdminListBundle\AdminList\FieldAlias;
11
use Kunstmaan\AdminListBundle\AdminList\FilterType\DBAL\EnumerationFilterType;
12
use Kunstmaan\AdminListBundle\AdminList\FilterType\DBAL\StringFilterType;
13
use Kunstmaan\AdminListBundle\Traits\ChangeableLimitTrait;
14
use Kunstmaan\TranslatorBundle\Entity\Translation;
15
16
/**
17
 * TranslationAdminListConfigurator
18
 */
19
class TranslationAdminListConfigurator extends AbstractDoctrineDBALAdminListConfigurator implements ChangeableLimitInterface
20
{
21
    use ChangeableLimitTrait;
22
23
    /**
24
     * @var array
25
     */
26
    protected $locales;
27
28
    /**
29
     * @var string
30
     */
31
    protected $locale;
32
33
    /**
34
     * @var Field[]
35
     */
36
    private $exportFields = [];
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
37
38
    public function __construct(Connection $connection, array $locales)
39
    {
40
        parent::__construct($connection);
41
        $this->locales = $locales;
42
        $this->setCountField('CONCAT(b.translation_id)');
43
    }
44
45
    /**
46
     * Configure filters
47
     */
48
    public function buildFilters()
49
    {
50
        $this->addFilter('status', new StringFilterType('status'), 'kuma_translator.adminlist.filter.status');
51
        $this->addFilter('domain', new StringFilterType('domain'), 'kuma_translator.adminlist.filter.domain');
52
        $this->addFilter('keyword', new StringFilterType('keyword'), 'kuma_translator.adminlist.filter.keyword');
53
        $this->addFilter('text', new StringFilterType('text'), 'kuma_translator.adminlist.filter.text');
54
        $this->addFilter('locale', new EnumerationFilterType('locale'), 'kuma_translator.adminlist.filter.locale', array_combine(
55
            $this->locales,
56
            $this->locales
57
        ));
58
    }
59
60
    /**
61
     * Configure the visible columns
62
     */
63
    public function buildFields()
64
    {
65
        $this->addField('domain', 'kuma_translator.adminlist.header.domain', true);
66
        $this->addField('keyword', 'kuma_translator.adminlist.header.keyword', true);
67
        $this->addField('status', 'kuma_translator.adminlist.header.status', true);
68
    }
69
70
    public function getExportFields()
71
    {
72
        if (empty($this->exportFields)) {
73
            $this->addExportField('domain', 'kuma_translator.adminlist.header.domain');
74
            $this->addExportField('keyword', 'kuma_translator.adminlist.header.keyword');
75
76
            $this->locales = array_unique($this->locales);
77
            // Field building hack...
78
            foreach ($this->locales as $locale) {
79
                $this->addExportField($locale, strtoupper($locale));
80
            }
81
82
            $this->addExportField('status', 'kuma_translator.adminlist.header.status');
83
        }
84
85
        return $this->exportFields;
86
    }
87
88
    public function addExportField($name, $header, $template = null, FieldAlias $alias = null)
89
    {
90
        $this->exportFields[] = new Field($name, $header);
91
92
        return $this;
93
    }
94
95
    /**
96
     * @return bool
97
     */
98
    public function canAdd()
99
    {
100
        return true;
101
    }
102
103
    /**
104
     * @param object|array $item
105
     *
106
     * @return bool
107
     */
108
    public function canEdit($item)
109
    {
110
        return false;
111
    }
112
113
    /**
114
     * @param object|array $item
115
     *
116
     * @return bool
117
     */
118
    public function canEditInline($item)
119
    {
120
        return true;
121
    }
122
123
    /**
124
     * @return bool
125
     */
126
    public function canExport()
127
    {
128
        return true;
129
    }
130
131
    /**
132
     * Override path convention (because settings is a virtual admin subtree)
133
     *
134
     * @param string $suffix
0 ignored issues
show
Should the type for parameter $suffix not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
135
     *
136
     * @return string
137
     */
138 View Code Duplication
    public function getPathByConvention($suffix = null)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
139
    {
140
        if (empty($suffix)) {
141
            return sprintf('%s_settings_%ss', $this->getBundleName(), strtolower($this->getEntityName()));
142
        }
143
144
        return sprintf('%s_settings_%ss_%s', $this->getBundleName(), strtolower($this->getEntityName()), $suffix);
145
    }
146
147
    /**
148
     * {@inheritdoc}
149
     */
150
    public function getAdminType($item)
151
    {
152
        return null;
153
    }
154
155
    public function getBundleName()
156
    {
157
        return 'KunstmaanTranslatorBundle';
158
    }
159
160
    public function getEntityName()
161
    {
162
        return 'Translation';
163
    }
164
165
    public function getControllerPath()
166
    {
167
        return 'KunstmaanTranslatorBundle:Index';
168
    }
169
170
    /**
171
     * @return QueryBuilder|null
172
     */
173
    public function getQueryBuilder()
174
    {
175
        if (\is_null($this->queryBuilder)) {
176
            $this->queryBuilder = new QueryBuilder($this->connection);
177
            $this->queryBuilder
178
                ->select('DISTINCT b.translation_id AS id, b.keyword, b.domain, b.status')
179
                ->from('kuma_translation', 'b')
180
                ->andWhere('b.status != :statusstring')
181
                ->setParameter('statusstring', Translation::STATUS_DISABLED);
182
183
            // Apply filters
184
            $filters = $this->getFilterBuilder()->getCurrentFilters();
185
            $locales = [];
186
187
            $textValue = $textComparator = null;
188
            foreach ($filters as $filter) {
189
                if ($filter->getType() instanceof EnumerationFilterType && $filter->getColumnName() == 'locale') {
190
                    // Override default enumeration filter handling ... catch selected locales here
191
                    $data = $filter->getData();
192
                    $comparator = $filter->getType()->getComparator();
193
                    if ($comparator == 'in') {
194
                        $locales = $data['value'];
195
                    } elseif ($comparator == 'notin') {
196
                        $locales = array_diff($this->locales, $data['value']);
197
                    }
198
                } elseif ($filter->getType() instanceof StringFilterType && $filter->getColumnName() == 'text') {
199
                    // Override default text filter handling ...
200
                    $data = $filter->getData();
201
                    $textValue = $data['value'];
202
                    $textComparator = $data['comparator'];
203
                } else {
204
                    /* @var AbstractDBALFilterType $type */
205
                    $type = $filter->getType();
206
                    $type->setQueryBuilder($this->queryBuilder);
207
                    $filter->apply();
208
                }
209
            }
210
211
            if (!empty($locales)) {
212
                $this->locales = $locales;
213
            }
214
            $this->locales = array_unique($this->locales);
215
216
            // Field building hack...
217
            foreach ($this->locales as $locale) {
218
                $this->addField($locale, strtoupper($locale), false, '@KunstmaanTranslator/Translator/inline_edit.html.twig');
219
            }
220
221
            // Field filter hack...
222
            $this->addFilter('locale', new EnumerationFilterType('locale'), 'kuma_translator.adminlist.filter.locale', array_combine(
223
                $this->locales,
224
                $this->locales
225
            ));
226
227
            // Add join for every locale
228
            foreach ($this->locales as $locale) {
229
                $this->queryBuilder->addSelect('t_' . $locale . '.`text` AS ' . $locale);
230
                $this->queryBuilder->addSelect('t_' . $locale . '.id AS ' . $locale . '_id');
231
                $this->queryBuilder->leftJoin(
232
                    'b',
233
                    'kuma_translation',
234
                    't_' . $locale,
235
                    'b.keyword = t_' . $locale . '.keyword and b.domain = t_' . $locale . '.domain and t_' . $locale . '.locale=:locale_' . $locale
236
                );
237
                $this->queryBuilder->setParameter('locale_' . $locale, $locale);
238
            }
239
240
            // Apply text filter
241
            if (!\is_null($textValue) && !\is_null($textComparator)) {
242
                $orX = $this->queryBuilder->expr()->orX();
243
244
                foreach ($this->locales as $key => $locale) {
245
                    $uniqueId = 'txt_' . $key;
246
                    $expr = null;
247
                    switch ($textComparator) {
248
                        case 'equals':
249
                            $expr = $this->queryBuilder->expr()->eq('t_' . $locale . '.`text`', ':var_' . $uniqueId);
250
                            $this->queryBuilder->setParameter('var_' . $uniqueId, $textValue);
251
252
                            break;
253
                        case 'notequals':
254
                            $expr = $this->queryBuilder->expr()->neq('t_' . $locale . '.`text`', ':var_' . $uniqueId);
255
                            $this->queryBuilder->setParameter('var_' . $uniqueId, $textValue);
256
257
                            break;
258 View Code Duplication
                        case 'contains':
259
                            $expr = $this->queryBuilder->expr()->like('t_' . $locale . '.`text`', ':var_' . $uniqueId);
260
                            $this->queryBuilder->setParameter('var_' . $uniqueId, '%' . $textValue . '%');
261
262
                            break;
263 View Code Duplication
                        case 'doesnotcontain':
264
                            $expr = 't_' . $locale . '.`text`' . ' NOT LIKE :var_' . $uniqueId;
265
                            $this->queryBuilder->setParameter('var_' . $uniqueId, '%' . $textValue . '%');
266
267
                            break;
268
                        case 'startswith':
269
                            $expr = $this->queryBuilder->expr()->like('t_' . $locale . '.`text`', ':var_' . $uniqueId);
270
                            $this->queryBuilder->setParameter('var_' . $uniqueId, $textValue . '%');
271
272
                            break;
273
                        case 'endswith':
274
                            $expr = $this->queryBuilder->expr()->like('t_' . $locale . '.`text`', ':var_' . $uniqueId);
275
                            $this->queryBuilder->setParameter('var_' . $uniqueId, '%' . $textValue);
276
277
                            break;
278
                        case 'empty':
279
                            $expr = $this->queryBuilder->expr()->orX(
280
                                $this->queryBuilder->expr()->isNull('t_' . $locale . '.`text`'),
281
                                $this->queryBuilder->expr()->eq('t_' . $locale . '.`text`', '\'-\''),
282
                                $this->queryBuilder->expr()->eq('t_' . $locale . '.`text`', '\'\'')
283
                            );
284
285
                            break;
286
                    }
287
288
                    if (null !== $expr) {
289
                        $orX->add($expr);
290
                    }
291
                }
292
293
                $this->queryBuilder->andWhere($orX);
294
            }
295
296
            // Apply sorting
297 View Code Duplication
            if (!empty($this->orderBy)) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
298
                $orderBy = $this->orderBy;
299
                $this->queryBuilder->orderBy($orderBy, ($this->orderDirection == 'DESC' ? 'DESC' : 'ASC'));
300
            }
301
        }
302
303
        return $this->queryBuilder;
304
    }
305
}
306