1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* This file is part of cwdBootgridBundle |
4
|
|
|
* |
5
|
|
|
* (c)2016 cwd.at GmbH <[email protected]> |
6
|
|
|
* |
7
|
|
|
* For the full copyright and license information, please view the LICENSE |
8
|
|
|
* file that was distributed with this source code. |
9
|
|
|
*/ |
10
|
|
|
namespace Cwd\FancyGridBundle\Column; |
11
|
|
|
|
12
|
|
|
use bar\baz\source_with_namespace; |
13
|
|
|
use Cwd\FancyGridBundle\Grid\Exception\InvalidArgumentException; |
14
|
|
|
use Symfony\Component\OptionsResolver\OptionsResolver; |
15
|
|
|
use Symfony\Component\PropertyAccess\PropertyAccessor; |
16
|
|
|
use Symfony\Component\Translation\TranslatorInterface; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Class AbstractColumn |
20
|
|
|
* @package Cwd\FancyGridBundle\Column |
21
|
|
|
* @author Ludwig Ruderstaler <[email protected]> |
22
|
|
|
*/ |
23
|
|
|
abstract class AbstractColumn implements ColumnInterface |
24
|
|
|
{ |
25
|
|
|
/** |
26
|
|
|
* @var string |
27
|
|
|
*/ |
28
|
|
|
protected $name; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @var string |
32
|
|
|
*/ |
33
|
|
|
|
34
|
|
|
protected $field; |
35
|
|
|
/** |
36
|
|
|
* @var array |
37
|
|
|
*/ |
38
|
|
|
protected $options = []; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @var TranslatorInterface |
42
|
|
|
*/ |
43
|
|
|
protected $translator; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* AbstractColumn constructor. |
47
|
|
|
* @param string $name |
48
|
|
|
* @param string $field |
49
|
|
|
* @param array $options |
50
|
|
|
*/ |
51
|
|
|
public function __construct($name, $field, array $options = []) |
52
|
|
|
{ |
53
|
|
|
$resolver = new OptionsResolver(); |
54
|
|
|
$this->configureOptions($resolver); |
55
|
|
|
|
56
|
|
|
$this->options = $resolver->resolve($options); |
57
|
|
|
$this->name = $name; |
58
|
|
|
$this->field = $field; |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @return string |
63
|
|
|
*/ |
64
|
|
|
public function getName() |
65
|
|
|
{ |
66
|
|
|
return $this->name; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @return string |
71
|
|
|
*/ |
72
|
|
|
public function getField() |
73
|
|
|
{ |
74
|
|
|
return $this->field; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* @param mixed $value |
79
|
|
|
* @param mixed $object |
80
|
|
|
* @param mixed $primary |
81
|
|
|
* @param \Twig_Environment $twig |
82
|
|
|
* |
83
|
|
|
* @return mixed |
84
|
|
|
*/ |
85
|
|
|
public function render($value, $object, $primary, \Twig_Environment $twig) |
86
|
|
|
{ |
87
|
|
|
/** dont use twig if no template is provided */ |
88
|
|
|
if (null === $this->getOption('template')) { |
89
|
|
|
return $value; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
return $this->renderTemplate( |
93
|
|
|
$twig, |
94
|
|
|
$this->getOption('template'), |
95
|
|
|
[ |
96
|
|
|
'value' => $value, |
97
|
|
|
'object' => $object, |
98
|
|
|
'primary' => $primary, |
99
|
|
|
] |
100
|
|
|
); |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* @param \Twig_Environment $twig |
105
|
|
|
* @param string $template |
106
|
|
|
* @param array $options |
107
|
|
|
* |
108
|
|
|
* @return string |
109
|
|
|
*/ |
110
|
|
|
protected function renderTemplate(\Twig_Environment $twig, $template, $options) |
111
|
|
|
{ |
112
|
|
|
$options = array_merge($options, $this->getOptions()); |
113
|
|
|
|
114
|
|
|
return $twig->render($template, $options); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* set defaults options |
119
|
|
|
* @param OptionsResolver $resolver |
120
|
|
|
*/ |
121
|
|
|
public function configureOptions(OptionsResolver $resolver) |
122
|
|
|
{ |
123
|
|
|
$resolver->setDefaults(array( |
124
|
|
|
'hidden' => false, |
125
|
|
|
'cellAlign' => 'left', |
126
|
|
|
'draggable' => false, |
127
|
|
|
'editable' => false, |
128
|
|
|
'flex' => 1, |
129
|
|
|
'index' => '', |
130
|
|
|
'lockable' => false, |
131
|
|
|
'locked' => false, |
132
|
|
|
'maxWidth' => null, |
133
|
|
|
'width' => null, |
134
|
|
|
'title' => null, |
135
|
|
|
'sortable' => true, |
136
|
|
|
'searchable' => true, |
137
|
|
|
'type' => 'string', |
138
|
|
|
'ellipsis' => true, |
139
|
|
|
'filter' => [ |
140
|
|
|
'header' => true, |
141
|
|
|
'headerNote' => true, |
142
|
|
|
], |
143
|
|
|
|
144
|
|
|
'translation_domain' => null, |
145
|
|
|
'translatable' => false, |
146
|
|
|
'attr' => array(), |
147
|
|
|
'template' => null, |
148
|
|
|
|
149
|
|
|
// Legacy |
150
|
|
|
'identifier' => null, |
151
|
|
|
'label' => null, |
152
|
|
|
'visible' => null, |
153
|
|
|
)); |
154
|
|
|
|
155
|
|
|
$resolver->setAllowedTypes('attr', 'array'); |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* render options as data-* string |
160
|
|
|
* @return string |
161
|
|
|
*/ |
162
|
|
|
public function renderOptions() |
163
|
|
|
{ |
164
|
|
|
$printOptions = [ |
165
|
|
|
'index' => $this->getName(), |
166
|
|
|
]; |
167
|
|
|
|
168
|
|
|
if ($this->getOption('visible')) { |
169
|
|
|
$printOptions['hidden'] = $this->getOption('visible'); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
if ($this->getOption('label')) { |
173
|
|
|
$printOptions['title'] = $this->translator->trans($this->getOption('label'), $this->getOptions('translation_domain')); |
|
|
|
|
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
$options = $this->options; |
177
|
|
|
|
178
|
|
|
foreach ($options as $key => $value) { |
179
|
|
|
// Ignore this options they are used differently |
180
|
|
|
if (in_array($key, ['attr', 'template', 'header_align', 'format','label', 'translation_domain', 'translatable', 'visible', 'identifier', 'index'])) { |
181
|
|
|
continue; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
// if null we dont need to print the option |
185
|
|
|
if (null === $value) { |
186
|
|
|
continue; |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
//if (is_bool($value)) { |
|
|
|
|
190
|
|
|
// $value = ($value) ? 'true' : 'false'; |
|
|
|
|
191
|
|
|
//} |
192
|
|
|
|
193
|
|
|
//$printOptions['data-'.str_replace('_', '-', $key)] = $value; |
|
|
|
|
194
|
|
|
$printOptions[$key] = $value; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
//$dataAttributes = array_map(function ($value, $key) { |
|
|
|
|
198
|
|
|
// return sprintf('%s="%s"', $key, $value); |
|
|
|
|
199
|
|
|
//}, array_values($printOptions), array_keys($printOptions)); |
|
|
|
|
200
|
|
|
|
201
|
|
|
return $printOptions; |
|
|
|
|
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
/** |
205
|
|
|
* @param mixed $object |
206
|
|
|
* @param string $field |
207
|
|
|
* @param string $primary |
208
|
|
|
* @param PropertyAccessor $accessor |
209
|
|
|
* |
210
|
|
|
* @return mixed |
211
|
|
|
*/ |
212
|
|
|
public function getValue($object, $field, $primary, $accessor) |
213
|
|
|
{ |
214
|
|
|
/** Special case handling for e.g. count() */ |
215
|
|
|
if (is_array($object) && isset($object[$field])) { |
216
|
|
|
return $object[$field]; |
217
|
|
|
} elseif (is_array($object)) { |
218
|
|
|
$object = $object[0]; |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
if (!$accessor->isReadable($object, $field)) { |
222
|
|
|
// if not found, try to strip alias. |
223
|
|
|
if (strstr($field, '.')) { |
224
|
|
|
$field = substr($field, strpos($field, '.')+1); |
225
|
|
|
} |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
if (!$accessor->isReadable($object, $field)) { |
229
|
|
|
/* |
|
|
|
|
230
|
|
|
throw new InvalidArgumentException( |
231
|
|
|
sprintf( |
232
|
|
|
'The Field "%s" could not be found in Object of type "%s"', |
233
|
|
|
$field, |
234
|
|
|
get_class($object) |
235
|
|
|
) |
236
|
|
|
); |
237
|
|
|
*/ |
238
|
|
|
return null; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
return $accessor->getValue($object, $field); |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
/** |
245
|
|
|
* @param string $name |
246
|
|
|
* @return bool |
247
|
|
|
*/ |
248
|
|
|
public function hasOption($name) |
249
|
|
|
{ |
250
|
|
|
return array_key_exists($name, $this->options); |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
/** |
254
|
|
|
* @param string $name |
255
|
|
|
* @param string|null $default |
256
|
|
|
* @return misc |
257
|
|
|
*/ |
258
|
|
|
public function getOption($name, $default = null) |
259
|
|
|
{ |
260
|
|
|
return array_key_exists($name, $this->options) ? $this->options[$name] : $default; |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
/** |
264
|
|
|
* @return array |
265
|
|
|
*/ |
266
|
|
|
public function getOptions() |
267
|
|
|
{ |
268
|
|
|
return $this->options; |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
/** |
272
|
|
|
* @return TranslatorInterface |
273
|
|
|
*/ |
274
|
|
|
public function getTranslator() |
275
|
|
|
{ |
276
|
|
|
return $this->translator; |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
/** |
280
|
|
|
* @param TranslatorInterface $translator |
281
|
|
|
*/ |
282
|
|
|
public function setTranslator(TranslatorInterface $translator) |
283
|
|
|
{ |
284
|
|
|
$this->translator = $translator; |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
|
288
|
|
|
} |
289
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.