1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace JeroenNoten\LaravelAdminLte\Console\PackageResources; |
4
|
|
|
|
5
|
|
|
use Illuminate\Support\Facades\File; |
6
|
|
|
use JeroenNoten\LaravelAdminLte\Helpers\CommandHelper; |
7
|
|
|
|
8
|
|
|
class PluginsResource extends PackageResource |
9
|
|
|
{ |
10
|
|
|
/** |
11
|
|
|
* The available plugins data. A plugin can contain next data keys: |
12
|
|
|
* - name: The name of the plugin. |
13
|
|
|
* - source: The source of the plugin (relative to base source) |
14
|
|
|
* - target: The target of the plugin (relative to base target) |
15
|
|
|
* - resources: An array with resources data items. |
16
|
|
|
* - ignore: A list of file patterns to ignore. |
17
|
|
|
* - recursive: Whether to copy files recursively (default is true). |
18
|
|
|
* |
19
|
|
|
* When the target is not specified, the source will be used as the |
20
|
|
|
* relative path to the base target destination. A resource can contain the |
21
|
|
|
* same keys that are availables for a plugin. |
22
|
|
|
* |
23
|
|
|
* @var array |
24
|
|
|
*/ |
25
|
|
|
protected $plugins = [ |
26
|
|
|
'bootstrap4DualListbox' => [ |
27
|
|
|
'name' => 'Bootstrap4 Dual Listbox', |
28
|
|
|
'source' => 'bootstrap4-duallistbox', |
29
|
|
|
], |
30
|
|
|
'bootstrapColorpicker' => [ |
31
|
|
|
'name' => 'Bootstrap Colorpicker', |
32
|
|
|
'source' => 'bootstrap-colorpicker', |
33
|
|
|
], |
34
|
|
|
'bootstrapSlider' => [ |
35
|
|
|
'name' => 'Bootstrap Slider', |
36
|
|
|
'source' => 'bootstrap-slider', |
37
|
|
|
], |
38
|
|
|
'bootstrapSwitch' => [ |
39
|
|
|
'name' => 'Bootstrap Switch', |
40
|
|
|
'source' => 'bootstrap-switch', |
41
|
|
|
], |
42
|
|
|
'bsCustomFileInput' => [ |
43
|
|
|
'name' => 'bs-custom-file-input', |
44
|
|
|
'source' => 'bs-custom-file-input', |
45
|
|
|
], |
46
|
|
|
'chartJs' => [ |
47
|
|
|
'name' => 'Chart.js', |
48
|
|
|
'source' => 'chart.js', |
49
|
|
|
], |
50
|
|
|
'datatables' => [ |
51
|
|
|
'name' => 'Datatables', |
52
|
|
|
'resources' => [ |
53
|
|
|
['source' => 'datatables', 'target' => 'datatables/js'], |
54
|
|
|
['source' => 'datatables-bs4', 'target' => 'datatables'], |
55
|
|
|
], |
56
|
|
|
], |
57
|
|
|
'datatablesPlugins' => [ |
58
|
|
|
'name' => 'Datatables Plugins', |
59
|
|
|
'resources' => [ |
60
|
|
|
['source' => 'datatables-autofill', 'target' => 'datatables-plugins/autofill'], |
61
|
|
|
['source' => 'datatables-buttons', 'target' => 'datatables-plugins/buttons'], |
62
|
|
|
['source' => 'datatables-colreorder', 'target' => 'datatables-plugins/colreorder'], |
63
|
|
|
['source' => 'datatables-fixedcolumns', 'target' => 'datatables-plugins/fixedcolumns'], |
64
|
|
|
['source' => 'datatables-fixedheader', 'target' => 'datatables-plugins/fixedheader'], |
65
|
|
|
['source' => 'datatables-keytable', 'target' => 'datatables-plugins/keytable'], |
66
|
|
|
['source' => 'datatables-responsive', 'target' => 'datatables-plugins/responsive'], |
67
|
|
|
['source' => 'datatables-rowgroup', 'target' => 'datatables-plugins/rowgroup'], |
68
|
|
|
['source' => 'datatables-rowreorder', 'target' => 'datatables-plugins/rowreorder'], |
69
|
|
|
['source' => 'datatables-scroller', 'target' => 'datatables-plugins/scroller'], |
70
|
|
|
['source' => 'datatables-select', 'target' => 'datatables-plugins/select'], |
71
|
|
|
['source' => 'pdfmake', 'target' => 'datatables-plugins/pdfmake'], |
72
|
|
|
['source' => 'jszip', 'target' => 'datatables-plugins/jszip'], |
73
|
|
|
], |
74
|
|
|
], |
75
|
|
|
'daterangepicker' => [ |
76
|
|
|
'name' => 'Date Range Picker', |
77
|
|
|
'resources' => [ |
78
|
|
|
['source' => 'daterangepicker'], |
79
|
|
|
['source' => 'moment'], |
80
|
|
|
], |
81
|
|
|
], |
82
|
|
|
'ekkoLightbox' => [ |
83
|
|
|
'name' => 'Ekko Lightbox', |
84
|
|
|
'source' => 'ekko-lightbox', |
85
|
|
|
], |
86
|
|
|
'fastclick' => [ |
87
|
|
|
'name' => 'FastClick', |
88
|
|
|
'source' => 'fastclick', |
89
|
|
|
], |
90
|
|
|
'filterizr' => [ |
91
|
|
|
'name' => 'Filterizr', |
92
|
|
|
'source' => 'filterizr', |
93
|
|
|
'ignore' => ['*.d.ts'], |
94
|
|
|
'recursive' => false, |
95
|
|
|
], |
96
|
|
|
'flagIconCss' => [ |
97
|
|
|
'name' => 'Flag Icon Css', |
98
|
|
|
'source' => 'flag-icon-css', |
99
|
|
|
], |
100
|
|
|
'flot' => [ |
101
|
|
|
'name' => 'Flot', |
102
|
|
|
'source' => 'flot', |
103
|
|
|
], |
104
|
|
|
'fullcalendar' => [ |
105
|
|
|
'name' => 'Fullcalendar', |
106
|
|
|
'source' => 'fullcalendar', |
107
|
|
|
'ignore' => ['*.d.ts', '*.json', '*.md'], |
108
|
|
|
], |
109
|
|
|
'icheckBootstrap' => [ |
110
|
|
|
'name' => 'iCheck Bootstrap', |
111
|
|
|
'source' => 'icheck-bootstrap', |
112
|
|
|
'ignore' => ['*.json', '*.md'], |
113
|
|
|
], |
114
|
|
|
'inputmask' => [ |
115
|
|
|
'name' => 'InputMask', |
116
|
|
|
'source' => 'inputmask', |
117
|
|
|
], |
118
|
|
|
'ionRangslider' => [ |
119
|
|
|
'name' => 'Ion.RangeSlider', |
120
|
|
|
'source' => 'ion-rangeslider', |
121
|
|
|
'ignore' => ['*.json', '*.md', '.editorconfig'], |
122
|
|
|
], |
123
|
|
|
'jqueryKnob' => [ |
124
|
|
|
'name' => 'jQuery Knob', |
125
|
|
|
'source' => 'jquery-knob', |
126
|
|
|
], |
127
|
|
|
'jqueryMapael' => [ |
128
|
|
|
'name' => 'jQuery Mapael', |
129
|
|
|
'resources' => [ |
130
|
|
|
['source' => 'jquery-mapael'], |
131
|
|
|
['source' => 'raphael'], |
132
|
|
|
['source' => 'jquery-mousewheel'], |
133
|
|
|
], |
134
|
|
|
'ignore' => ['*.json', '*.md', '.editorconfig'], |
135
|
|
|
], |
136
|
|
|
'jqueryUi' => [ |
137
|
|
|
'name' => 'jQuery UI', |
138
|
|
|
'resources' => [ |
139
|
|
|
['source' => 'jquery-ui'], |
140
|
|
|
['source' => 'jquery-ui/images'], |
141
|
|
|
], |
142
|
|
|
'recursive' => false, |
143
|
|
|
], |
144
|
|
|
'jqueryValidation' => [ |
145
|
|
|
'name' => 'jQuery Validation', |
146
|
|
|
'source' => 'jquery-validation', |
147
|
|
|
], |
148
|
|
|
'jqvmap' => [ |
149
|
|
|
'name' => 'jQVMap', |
150
|
|
|
'source' => 'jqvmap', |
151
|
|
|
], |
152
|
|
|
'jsgrid' => [ |
153
|
|
|
'name' => 'jsGrid', |
154
|
|
|
'resources' => [ |
155
|
|
|
['source' => 'jsgrid'], |
156
|
|
|
['source' => 'jsgrid/i18n'], |
157
|
|
|
], |
158
|
|
|
'recursive' => false, |
159
|
|
|
], |
160
|
|
|
'paceProgress' => [ |
161
|
|
|
'name' => 'Pace Progress', |
162
|
|
|
'source' => 'pace-progress', |
163
|
|
|
], |
164
|
|
|
'select2' => [ |
165
|
|
|
'name' => 'Select 2 with Bootstrap 4 Theme', |
166
|
|
|
'resources' => [ |
167
|
|
|
['source' => 'select2'], |
168
|
|
|
['source' => 'select2-bootstrap4-theme'], |
169
|
|
|
], |
170
|
|
|
'ignore' => ['*.json', '*.md'], |
171
|
|
|
], |
172
|
|
|
'sparklines' => [ |
173
|
|
|
'name' => 'Sparklines', |
174
|
|
|
'source' => 'sparklines', |
175
|
|
|
], |
176
|
|
|
'summernote' => [ |
177
|
|
|
'name' => 'Summernote', |
178
|
|
|
'source' => 'summernote', |
179
|
|
|
], |
180
|
|
|
'sweetalert2' => [ |
181
|
|
|
'name' => 'Sweetalert 2 with Bootstrap 4 Theme', |
182
|
|
|
'resources' => [ |
183
|
|
|
['source' => 'sweetalert2'], |
184
|
|
|
['source' => 'sweetalert2-theme-bootstrap-4'], |
185
|
|
|
], |
186
|
|
|
], |
187
|
|
|
'tempusdominusBootstrap4' => [ |
188
|
|
|
'name' => 'Tempus Dominus for Bootstrap 4', |
189
|
|
|
'resources' => [ |
190
|
|
|
['source' => 'tempusdominus-bootstrap-4'], |
191
|
|
|
['source' => 'moment'], |
192
|
|
|
], |
193
|
|
|
], |
194
|
|
|
'toastr' => [ |
195
|
|
|
'name' => 'Toastr', |
196
|
|
|
'source' => 'toastr', |
197
|
|
|
], |
198
|
|
|
]; |
199
|
|
|
|
200
|
|
|
/** |
201
|
|
|
* Create a new resource instance. |
202
|
|
|
* |
203
|
|
|
* @return void |
204
|
|
|
*/ |
205
|
23 |
|
public function __construct() |
206
|
|
|
{ |
207
|
|
|
// Fill the basic resource data. |
208
|
|
|
|
209
|
23 |
|
$this->description = 'The set of extra plugins available with AdminLTE'; |
210
|
23 |
|
$this->required = false; |
211
|
|
|
|
212
|
|
|
// Define the base source folder of the plugins. |
213
|
|
|
|
214
|
23 |
|
$this->source = base_path('vendor/almasaeed2010/adminlte/plugins'); |
215
|
|
|
|
216
|
|
|
// Define the base target destination for the plugins. |
217
|
|
|
|
218
|
23 |
|
$this->target = public_path('vendor'); |
219
|
|
|
|
220
|
|
|
// Fill the set of installation messages templates. |
221
|
|
|
|
222
|
23 |
|
$this->messages = [ |
223
|
23 |
|
'install' => 'Do you want to plublish the :plugin plugin?', |
224
|
23 |
|
'overwrite' => 'The :plugin plugin was already published. Want to replace?', |
225
|
23 |
|
'remove' => 'Do you really want to remove the :plugin plugin?', |
226
|
23 |
|
]; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* Gets the plugins source data. |
231
|
|
|
* |
232
|
|
|
* @param string $pluginKey A plugin key |
233
|
|
|
* @return array |
234
|
|
|
*/ |
235
|
6 |
|
public function getSourceData($pluginKey = null) |
236
|
|
|
{ |
237
|
|
|
// Check if we need to get data of a specific AdminLTE plugin. |
238
|
|
|
|
239
|
6 |
|
if (! empty($pluginKey)) { |
240
|
6 |
|
return $this->plugins[$pluginKey] ?? []; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
// Otherwise, return all the AdminLTE plugins data. |
244
|
|
|
|
245
|
2 |
|
return $this->plugins; |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
/** |
249
|
|
|
* Installs or publishes the specified plugin. |
250
|
|
|
* |
251
|
|
|
* @param string $pluginKey A plugin key |
252
|
|
|
* @return void |
253
|
|
|
*/ |
254
|
6 |
|
public function install($pluginKey = null) |
255
|
|
|
{ |
256
|
6 |
|
if (isset($pluginKey) && isset($this->plugins[$pluginKey])) { |
257
|
6 |
|
$plugin = $this->preparePlugin($this->plugins[$pluginKey]); |
258
|
6 |
|
$this->installPlugin($plugin); |
259
|
|
|
} |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
/** |
263
|
|
|
* Uninstalls the specified plugin. |
264
|
|
|
* |
265
|
|
|
* @param string $pluginKey A plugin key |
266
|
|
|
* @return void |
267
|
|
|
*/ |
268
|
6 |
|
public function uninstall($pluginKey = null) |
269
|
|
|
{ |
270
|
6 |
|
if (isset($pluginKey) && isset($this->plugins[$pluginKey])) { |
271
|
6 |
|
$plugin = $this->preparePlugin($this->plugins[$pluginKey]); |
272
|
6 |
|
$this->uninstallPlugin($plugin); |
273
|
|
|
} |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
/** |
277
|
|
|
* Checks whether a plugin already exists in the target location. |
278
|
|
|
* |
279
|
|
|
* @param string $pluginKey A plugin key |
280
|
|
|
* @return bool |
281
|
|
|
*/ |
282
|
5 |
|
public function exists($pluginKey = null) |
283
|
|
|
{ |
284
|
5 |
|
if (isset($pluginKey) && isset($this->plugins[$pluginKey])) { |
285
|
4 |
|
$plugin = $this->preparePlugin($this->plugins[$pluginKey]); |
286
|
|
|
|
287
|
4 |
|
return $this->pluginExists($plugin); |
288
|
|
|
} |
289
|
|
|
|
290
|
1 |
|
return false; |
291
|
|
|
} |
292
|
|
|
|
293
|
|
|
/** |
294
|
|
|
* Checks whether a plugin is correctly installed, i.e. if the source items |
295
|
|
|
* matches with the items available at the target location. |
296
|
|
|
* |
297
|
|
|
* @param string $pluginKey A plugin key |
298
|
|
|
* @return bool |
299
|
|
|
*/ |
300
|
7 |
|
public function installed($pluginKey = null) |
301
|
|
|
{ |
302
|
7 |
|
if (isset($pluginKey) && isset($this->plugins[$pluginKey])) { |
303
|
6 |
|
$plugin = $this->preparePlugin($this->plugins[$pluginKey]); |
304
|
|
|
|
305
|
6 |
|
return $this->pluginInstalled($plugin); |
306
|
|
|
} |
307
|
|
|
|
308
|
1 |
|
return false; |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
/** |
312
|
|
|
* Prepares a plugin with some sort of normalizations in its data. |
313
|
|
|
* |
314
|
|
|
* @param array $plugin An array with the plugin data |
315
|
|
|
* @return array |
316
|
|
|
*/ |
317
|
6 |
|
protected function preparePlugin($plugin) |
318
|
|
|
{ |
319
|
|
|
// Add source and target when not defined. |
320
|
|
|
|
321
|
6 |
|
$plugin['source'] = $plugin['source'] ?? ''; |
322
|
6 |
|
$plugin['target'] = $plugin['target'] ?? $plugin['source']; |
323
|
|
|
|
324
|
|
|
// Add fully qualified paths and default values. |
325
|
|
|
|
326
|
6 |
|
$DS = DIRECTORY_SEPARATOR; |
327
|
6 |
|
$plugin['source'] = $this->source.$DS.$plugin['source']; |
328
|
6 |
|
$plugin['target'] = $this->target.$DS.$plugin['target']; |
329
|
6 |
|
$plugin['ignore'] = $plugin['ignore'] ?? []; |
330
|
6 |
|
$plugin['recursive'] = $plugin['recursive'] ?? true; |
331
|
|
|
|
332
|
|
|
// Add fully qualified paths and default values on the resources. |
333
|
|
|
|
334
|
6 |
|
if (isset($plugin['resources'])) { |
335
|
3 |
|
foreach ($plugin['resources'] as $key => $res) { |
336
|
3 |
|
$res['target'] = $res['target'] ?? $res['source']; |
337
|
3 |
|
$res['source'] = $plugin['source'].$DS.$res['source']; |
338
|
3 |
|
$res['target'] = $plugin['target'].$DS.$res['target']; |
339
|
3 |
|
$res['ignore'] = $res['ignore'] ?? $plugin['ignore']; |
340
|
3 |
|
$res['recursive'] = $res['recursive'] ?? $plugin['recursive']; |
341
|
3 |
|
$plugin['resources'][$key] = $res; |
342
|
|
|
} |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
// Return normalized plugin data. |
346
|
|
|
|
347
|
6 |
|
return $plugin; |
348
|
|
|
} |
349
|
|
|
|
350
|
|
|
/** |
351
|
|
|
* Installs the specified AdminLTE plugin. |
352
|
|
|
* |
353
|
|
|
* @param array $plugin An array with the plugin data |
354
|
|
|
* @return void |
355
|
|
|
*/ |
356
|
6 |
|
protected function installPlugin($plugin) |
357
|
|
|
{ |
358
|
|
|
// Check if we need to export the entire plugin. |
359
|
|
|
|
360
|
6 |
|
if (! isset($plugin['resources'])) { |
361
|
6 |
|
return $this->publishResource($plugin); |
|
|
|
|
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
// Otherwise, publish only the specified plugin resources. |
365
|
|
|
|
366
|
2 |
|
foreach ($plugin['resources'] as $res) { |
367
|
2 |
|
$this->publishResource($res); |
368
|
|
|
} |
369
|
|
|
} |
370
|
|
|
|
371
|
|
|
/** |
372
|
|
|
* Publishes the specified resource (usually a file or folder). |
373
|
|
|
* |
374
|
|
|
* @param array $res An array with the resource data |
375
|
|
|
* @return void |
376
|
|
|
*/ |
377
|
6 |
|
protected function publishResource($res) |
378
|
|
|
{ |
379
|
|
|
// Check whether the resource is a file or a directory. |
380
|
|
|
|
381
|
6 |
|
if (File::isDirectory($res['source'])) { |
382
|
6 |
|
CommandHelper::copyDirectory( |
383
|
6 |
|
$res['source'], |
384
|
6 |
|
$res['target'], |
385
|
6 |
|
$res['force'] ?? true, |
386
|
6 |
|
$res['recursive'] ?? true, |
387
|
6 |
|
$res['ignore'] ?? [] |
388
|
6 |
|
); |
389
|
|
|
} else { |
390
|
|
|
File::ensureDirectoryExists(File::dirname($res['target'])); |
391
|
|
|
File::copy($res['source'], $res['target']); |
392
|
|
|
} |
393
|
|
|
} |
394
|
|
|
|
395
|
|
|
/** |
396
|
|
|
* Checks whether the specified plugin already exists in the target |
397
|
|
|
* location. |
398
|
|
|
* |
399
|
|
|
* @param array $plugin An array with the plugin data |
400
|
|
|
* @return bool |
401
|
|
|
*/ |
402
|
4 |
|
protected function pluginExists($plugin) |
403
|
|
|
{ |
404
|
|
|
// When the plugin is not a resources list, just check if target exists. |
405
|
|
|
|
406
|
4 |
|
if (! isset($plugin['resources'])) { |
407
|
4 |
|
return File::exists($plugin['target']); |
408
|
|
|
} |
409
|
|
|
|
410
|
|
|
// Otherwise, check if any of the plugin resources already exists. |
411
|
|
|
|
412
|
2 |
|
foreach ($plugin['resources'] as $res) { |
413
|
2 |
|
if (File::exists($res['target'])) { |
414
|
1 |
|
return true; |
415
|
|
|
} |
416
|
|
|
} |
417
|
|
|
|
418
|
2 |
|
return false; |
419
|
|
|
} |
420
|
|
|
|
421
|
|
|
/** |
422
|
|
|
* Checks whether the specified plugin is correctly installed. |
423
|
|
|
* |
424
|
|
|
* @param array $plugin An array with the plugin data |
425
|
|
|
* @return bool |
426
|
|
|
*/ |
427
|
6 |
|
protected function pluginInstalled($plugin) |
428
|
|
|
{ |
429
|
|
|
// Check whether the plugin has resources or not. |
430
|
|
|
|
431
|
6 |
|
if (! isset($plugin['resources'])) { |
432
|
6 |
|
return $this->resourceInstalled($plugin); |
433
|
|
|
} |
434
|
|
|
|
435
|
3 |
|
foreach ($plugin['resources'] as $res) { |
436
|
3 |
|
if (! $this->resourceInstalled($res)) { |
437
|
3 |
|
return false; |
438
|
|
|
} |
439
|
|
|
} |
440
|
|
|
|
441
|
2 |
|
return true; |
442
|
|
|
} |
443
|
|
|
|
444
|
|
|
/** |
445
|
|
|
* Checks whether the specified resource is correctly installed. |
446
|
|
|
* |
447
|
|
|
* @param array $res An array with the resource data |
448
|
|
|
* @return bool |
449
|
|
|
*/ |
450
|
6 |
|
protected function resourceInstalled($res) |
451
|
|
|
{ |
452
|
|
|
// Check whether the resource is a file or a directory. |
453
|
|
|
|
454
|
6 |
|
if (File::isDirectory($res['source'])) { |
455
|
6 |
|
return (bool) CommandHelper::compareDirectories( |
456
|
6 |
|
$res['source'], |
457
|
6 |
|
$res['target'], |
458
|
6 |
|
$res['recursive'] ?? true, |
459
|
6 |
|
$res['ignore'] ?? [] |
460
|
6 |
|
); |
461
|
|
|
} |
462
|
|
|
|
463
|
|
|
return CommandHelper::compareFiles($res['source'], $res['target']); |
464
|
|
|
} |
465
|
|
|
|
466
|
|
|
/** |
467
|
|
|
* Uninstalls the specified plugin. |
468
|
|
|
* |
469
|
|
|
* @param array $plugin An array with the plugin data |
470
|
|
|
* @return void |
471
|
|
|
*/ |
472
|
6 |
|
protected function uninstallPlugin($plugin) |
473
|
|
|
{ |
474
|
|
|
// If the plugin doensn't have resources, remove the main target |
475
|
|
|
// location folder. |
476
|
|
|
|
477
|
6 |
|
if (! isset($plugin['resources'])) { |
478
|
6 |
|
return $this->uninstallResource($plugin); |
479
|
|
|
} |
480
|
|
|
|
481
|
|
|
// Otherwise, remove only the specified plugin resources. |
482
|
|
|
|
483
|
2 |
|
foreach ($plugin['resources'] as $res) { |
484
|
2 |
|
$this->uninstallResource($res); |
485
|
|
|
} |
486
|
|
|
} |
487
|
|
|
|
488
|
|
|
/** |
489
|
|
|
* Removes the specified resource (usually a folder). |
490
|
|
|
* |
491
|
|
|
* @param array $res An array with the resource data |
492
|
|
|
* @return bool |
493
|
|
|
*/ |
494
|
6 |
|
protected function uninstallResource($res) |
495
|
|
|
{ |
496
|
6 |
|
$target = $res['target']; |
497
|
|
|
|
498
|
|
|
// Uninstall the specified resource. Note the target location is always |
499
|
|
|
// a folder. When the target folder does not exists, we consider the |
500
|
|
|
// resource as uninstalled. |
501
|
|
|
|
502
|
6 |
|
if (File::isDirectory($target)) { |
503
|
6 |
|
File::deleteDirectory($target); |
504
|
|
|
} |
505
|
|
|
} |
506
|
|
|
} |
507
|
|
|
|
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()
can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.