Completed
Push — master ( 45acf5...a44dac )
by Philip
04:08
created

Controller   C

Complexity

Total Complexity 57

Size/Duplication

Total Lines 536
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 57
c 1
b 0
f 0
lcom 1
cbo 11
dl 0
loc 536
ccs 222
cts 222
cp 1
rs 6.433

16 Methods

Rating   Name   Duplication   Size   Complexity  
A modifyFilesAndSetFlashBag() 0 15 3
A setValidationFailedFlashes() 0 7 2
C modifyEntity() 0 34 7
A getAfterDeleteRedirectParameters() 0 15 3
C buildUpListFilter() 0 25 8
A getNotFoundPage() 0 9 1
A setLocaleAndCheckEntity() 0 9 2
A create() 0 8 1
B showList() 0 46 4
B show() 0 35 5
A edit() 0 10 2
B delete() 0 30 5
A renderFile() 0 11 4
A deleteFile() 0 17 4
A staticFile() 0 23 3
A setLocale() 0 14 3

How to fix   Complexity   

Complex Class

Complex classes like Controller often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Controller, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * This file is part of the CRUDlex package.
5
 *
6
 * (c) Philip Lehmann-Böhm <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace CRUDlex;
13
14
use League\Flysystem\Util\MimeType;
15
use Silex\Application;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\HttpFoundation\Response;
18
use Symfony\Component\HttpFoundation\StreamedResponse;
19
20
21
/**
22
 * This is the Controller offering all CRUD pages.
23
 *
24
 * It offers functions for this routes:
25
 *
26
 * "/resource/static" serving static resources
27
 *
28
 * "/{entity}/create" creation page of the entity
29
 *
30
 * "/{entity}" list page of the entity
31
 *
32
 * "/{entity}/{id}" details page of a single entity instance
33
 *
34
 * "/{entity}/{id}/edit" edit page of a single entity instance
35
 *
36
 * "/{entity}/{id}/delete" POST only deletion route for an entity instance
37
 *
38
 * "/{entity}/{id}/{field}/file" renders a file field of an entity instance
39
 *
40
 * "/{entity}/{id}/{field}/delete" POST only deletion of a file field of an entity instance
41
 */
42
class Controller {
43
44
    /**
45
     * Postprocesses the entity after modification by handling the uploaded
46
     * files and setting the flash.
47
     *
48
     * @param Application $app
49
     * the current application
50
     * @param AbstractData $crudData
51
     * the data instance of the entity
52
     * @param Entity $instance
53
     * the entity
54
     * @param string $entity
55
     * the name of the entity
56
     * @param string $mode
57
     * whether to 'edit' or to 'create' the entity
58
     *
59
     * @return null|\Symfony\Component\HttpFoundation\RedirectResponse
60
     * the HTTP response of this modification
61
     */
62 4
    protected function modifyFilesAndSetFlashBag(Application $app, AbstractData $crudData, Entity $instance, $entity, $mode)
63
    {
64 4
        $id          = $instance->get('id');
65 4
        $request     = $app['request_stack']->getCurrentRequest();
66 4
        $fileHandler = new FileHandler($app['crud.filesystem'], $crudData->getDefinition());
67 4
        $result      = $mode == 'edit' ? $fileHandler->updateFiles($crudData, $request, $instance, $entity) : $fileHandler->createFiles($crudData, $request, $instance, $entity);
68 4
        if (!$result) {
69 2
            return null;
70
        }
71 4
        $app['session']->getFlashBag()->add('success', $app['translator']->trans('crudlex.'.$mode.'.success', [
72 4
            '%label%' => $crudData->getDefinition()->getLabel(),
73 4
            '%id%' => $id
74
        ]));
75 4
        return $app->redirect($app['url_generator']->generate('crudShow', ['entity' => $entity, 'id' => $id]));
76
    }
77
78
    /**
79
     * Sets the flashes of a failed entity modification.
80
     *
81
     * @param Application $app
82
     * the current application
83
     * @param boolean $optimisticLocking
84
     * whether the optimistic locking failed
85
     * @param string $mode
86
     * the modification mode, either 'create' or 'edit'
87
     */
88 2
    protected function setValidationFailedFlashes(Application $app, $optimisticLocking, $mode)
89
    {
90 2
        $app['session']->getFlashBag()->add('danger', $app['translator']->trans('crudlex.'.$mode.'.error'));
91 2
        if ($optimisticLocking) {
92 1
            $app['session']->getFlashBag()->add('danger', $app['translator']->trans('crudlex.edit.locked'));
93
        }
94 2
    }
95
96
    /**
97
     * Validates and saves the new or updated entity and returns the appropriate HTTP
98
     * response.
99
     *
100
     * @param Application $app
101
     * the current application
102
     * @param AbstractData $crudData
103
     * the data instance of the entity
104
     * @param Entity $instance
105
     * the entity
106
     * @param string $entity
107
     * the name of the entity
108
     * @param boolean $edit
109
     * whether to edit (true) or to create (false) the entity
110
     *
111
     * @return Response
112
     * the HTTP response of this modification
113
     */
114 5
    protected function modifyEntity(Application $app, AbstractData $crudData, Entity $instance, $entity, $edit)
115
    {
116 5
        $fieldErrors = [];
117 5
        $mode        = $edit ? 'edit' : 'create';
118 5
        $request     = $app['request_stack']->getCurrentRequest();
119 5
        if ($request->getMethod() == 'POST') {
120 4
            $instance->populateViaRequest($request);
121 4
            $validator  = new EntityValidator($instance);
122 4
            $validation = $validator->validate($crudData, intval($request->get('version')));
123
124 4
            $fieldErrors = $validation['errors'];
125 4
            if (!$validation['valid']) {
126 2
                $optimisticLocking = isset($fieldErrors['version']);
127 2
                $this->setValidationFailedFlashes($app, $optimisticLocking, $mode);
128
            } else {
129 4
                $modified = $edit ? $crudData->update($instance) : $crudData->create($instance);
130 4
                $response = $modified ? $this->modifyFilesAndSetFlashBag($app, $crudData, $instance, $entity, $mode) : false;
131 4
                if ($response) {
132 4
                    return $response;
133
                }
134 2
                $app['session']->getFlashBag()->add('danger', $app['translator']->trans('crudlex.'.$mode.'.failed'));
135
            }
136
        }
137
138 3
        return $app['twig']->render($app['crud']->getTemplate('template', 'form', $entity), [
139 3
            'crud' => $app['crud'],
140 3
            'crudEntity' => $entity,
141 3
            'crudData' => $crudData,
142 3
            'entity' => $instance,
143 3
            'mode' => $mode,
144 3
            'fieldErrors' => $fieldErrors,
145 3
            'layout' => $app['crud']->getTemplate('layout', $mode, $entity)
146
        ]);
147
    }
148
149
    /**
150
     * Gets the parameters for the redirection after deleting an entity.
151
     *
152
     * @param Request $request
153
     * the current request
154
     * @param string $entity
155
     * the entity name
156
     * @param string $redirectPage
157
     * reference, where the page to redirect to will be stored
158
     *
159
     * @return array<string,string>
160
     * the parameters of the redirection, entity and id
161
     */
162 1
    protected function getAfterDeleteRedirectParameters(Request $request, $entity, &$redirectPage)
163
    {
164 1
        $redirectPage       = 'crudList';
165 1
        $redirectParameters = ['entity' => $entity];
166 1
        $redirectEntity     = $request->get('redirectEntity');
167 1
        $redirectId         = $request->get('redirectId');
168 1
        if ($redirectEntity && $redirectId) {
169 1
            $redirectPage       = 'crudShow';
170
            $redirectParameters = [
171 1
                'entity' => $redirectEntity,
172 1
                'id' => $redirectId
173
            ];
174
        }
175 1
        return $redirectParameters;
176
    }
177
178
    /**
179
     * Builds up the parameters of the list page filters.
180
     *
181
     * @param Request $request
182
     * the current application
183
     * @param EntityDefinition $definition
184
     * the current entity definition
185
     * @param array &$filter
186
     * will hold a map of fields to request parameters for the filters
187
     * @param boolean $filterActive
188
     * reference, will be true if at least one filter is active
189
     * @param array $filterToUse
190
     * reference, will hold a map of fields to integers (0 or 1) which boolean filters are active
191
     * @param array $filterOperators
192
     * reference, will hold a map of fields to operators for AbstractData::listEntries()
193
     */
194 4
    protected function buildUpListFilter(Request $request, EntityDefinition $definition, &$filter, &$filterActive, &$filterToUse, &$filterOperators)
195
    {
196 4
        foreach ($definition->getFilter() as $filterField) {
197 4
            $type                 = $definition->getType($filterField);
198 4
            $filter[$filterField] = $request->get('crudFilter'.$filterField);
199 4
            if ($filter[$filterField]) {
200 1
                $filterActive                  = true;
201 1
                $filterToUse[$filterField]     = $filter[$filterField];
202 1
                $filterOperators[$filterField] = '=';
203 1
                if ($type === 'boolean') {
204 1
                    $filterToUse[$filterField] = $filter[$filterField] == 'true' ? 1 : 0;
205 1
                } else if ($type === 'reference') {
206 1
                    $filter[$filterField] = ['id' => $filter[$filterField]];
207 1
                } else if ($type === 'many') {
208 1
                    $filter[$filterField] = array_map(function($value) {
209 1
                        return ['id' => $value];
210 1
                    }, $filter[$filterField]);
211 1
                    $filterToUse[$filterField] = $filter[$filterField];
212 1
                } else if (in_array($type, ['text', 'multiline', 'fixed'])) {
213 1
                    $filterToUse[$filterField]     = '%'.$filter[$filterField].'%';
214 4
                    $filterOperators[$filterField] = 'LIKE';
215
                }
216
            }
217
        }
218 4
    }
219
220
    /**
221
     * Generates the not found page.
222
     *
223
     * @param Application $app
224
     * the Silex application
225
     * @param string $error
226
     * the cause of the not found error
227
     *
228
     * @return Response
229
     * the rendered not found page with the status code 404
230
     */
231 9
    public function getNotFoundPage(Application $app, $error)
232
    {
233 9
        return new Response($app['twig']->render('@crud/notFound.twig', [
234 9
            'crud' => $app['crud'],
235 9
            'error' => $error,
236 9
            'crudEntity' => '',
237 9
            'layout' => $app['crud']->getTemplate('layout', '', '')
238 9
        ]), 404);
239
    }
240
241
    /**
242
     * Transfers the locale from the translator to CRUDlex and
243
     *
244
     * @param Request $request
245
     * @param Application $app
246
     * @return Response
0 ignored issues
show
Documentation introduced by
Should the return type not be Response|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
247
     */
248 9
    public function setLocaleAndCheckEntity(Request $request, Application $app)
249
    {
250 9
        $locale = $app['translator']->getLocale();
251 9
        $app['crud']->setLocale($locale);
252 9
        if (!$app['crud']->getData($request->get('entity'))) {
253 7
            return $this->getNotFoundPage($app, $app['translator']->trans('crudlex.entityNotFound'));
254
        }
255 9
        return null;
256
    }
257
258
    /**
259
     * The controller for the "create" action.
260
     *
261
     * @param Application $app
262
     * the Silex application
263
     * @param string $entity
264
     * the current entity
265
     *
266
     * @return Response
267
     * the HTTP response of this action
268
     */
269 4
    public function create(Application $app, $entity)
270
    {
271 4
        $crudData = $app['crud']->getData($entity);
272 4
        $instance = $crudData->createEmpty();
273 4
        $request  = $app['request_stack']->getCurrentRequest();
274 4
        $instance->populateViaRequest($request);
275 4
        return $this->modifyEntity($app, $crudData, $instance, $entity, false);
276
    }
277
278
    /**
279
     * The controller for the "show list" action.
280
     *
281
     * @param Request $request
282
     * the current request
283
     * @param Application $app
284
     * the Silex application
285
     * @param string $entity
286
     * the current entity
287
     *
288
     * @return Response
289
     * the HTTP response of this action or 404 on invalid input
290
     */
291 4
    public function showList(Request $request, Application $app, $entity)
292
    {
293 4
        $crudData   = $app['crud']->getData($entity);
294 4
        $definition = $crudData->getDefinition();
295
296 4
        $filter          = [];
297 4
        $filterActive    = false;
298 4
        $filterToUse     = [];
299 4
        $filterOperators = [];
300 4
        $this->buildUpListFilter($request, $definition, $filter, $filterActive, $filterToUse, $filterOperators);
301
302 4
        $pageSize = $definition->getPageSize();
303 4
        $total    = $crudData->countBy($definition->getTable(), $filterToUse, $filterOperators, true);
304 4
        $page     = abs(intval($request->get('crudPage', 0)));
305 4
        $maxPage  = intval($total / $pageSize);
306 4
        if ($total % $pageSize == 0) {
307 4
            $maxPage--;
308
        }
309 4
        if ($page > $maxPage) {
310 4
            $page = $maxPage;
311
        }
312 4
        $skip = $page * $pageSize;
313
314 4
        $sortField            = $request->get('crudSortField', $definition->getInitialSortField());
315 4
        $sortAscendingRequest = $request->get('crudSortAscending');
316 4
        $sortAscending        = $sortAscendingRequest !== null ? $sortAscendingRequest === 'true' : $definition->isInitialSortAscending();
317
318 4
        $entities = $crudData->listEntries($filterToUse, $filterOperators, $skip, $pageSize, $sortField, $sortAscending);
319
320 4
        return $app['twig']->render($app['crud']->getTemplate('template', 'list', $entity), [
321 4
            'crud' => $app['crud'],
322 4
            'crudEntity' => $entity,
323 4
            'crudData' => $crudData,
324 4
            'definition' => $definition,
325 4
            'entities' => $entities,
326 4
            'pageSize' => $pageSize,
327 4
            'maxPage' => $maxPage,
328 4
            'page' => $page,
329 4
            'total' => $total,
330 4
            'filter' => $filter,
331 4
            'filterActive' => $filterActive,
332 4
            'sortField' => $sortField,
333 4
            'sortAscending' => $sortAscending,
334 4
            'layout' => $app['crud']->getTemplate('layout', 'list', $entity)
335
        ]);
336
    }
337
338
    /**
339
     * The controller for the "show" action.
340
     *
341
     * @param Application $app
342
     * the Silex application
343
     * @param string $entity
344
     * the current entity
345
     * @param string $id
346
     * the instance id to show
347
     *
348
     * @return Response
349
     * the HTTP response of this action or 404 on invalid input
350
     */
351 6
    public function show(Application $app, $entity, $id)
352
    {
353 6
        $crudData = $app['crud']->getData($entity);
354 6
        $instance = $crudData->get($id);
355 6
        if (!$instance) {
356 1
            return $this->getNotFoundPage($app, $app['translator']->trans('crudlex.instanceNotFound'));
357
        }
358 6
        $definition = $crudData->getDefinition();
359
360 6
        $childrenLabelFields = $definition->getChildrenLabelFields();
361 6
        $children            = [];
362 6
        if (count($childrenLabelFields) > 0) {
363 3
            foreach ($definition->getChildren() as $child) {
364 3
                $childField      = $child[1];
365 3
                $childEntity     = $child[2];
366 3
                $childLabelField = array_key_exists($childEntity, $childrenLabelFields) ? $childrenLabelFields[$childEntity] : 'id';
367 3
                $childCrud       = $app['crud']->getData($childEntity);
368 3
                $children[]      = [
369 3
                    $childCrud->getDefinition()->getLabel(),
370 3
                    $childEntity,
371 3
                    $childLabelField,
372 3
                    $childCrud->listEntries([$childField => $instance->get('id')]),
373 3
                    $childField
374
                ];
375
            }
376
        }
377
378 6
        return $app['twig']->render($app['crud']->getTemplate('template', 'show', $entity), [
379 6
            'crud' => $app['crud'],
380 6
            'crudEntity' => $entity,
381 6
            'entity' => $instance,
382 6
            'children' => $children,
383 6
            'layout' => $app['crud']->getTemplate('layout', 'show', $entity)
384
        ]);
385
    }
386
387
    /**
388
     * The controller for the "edit" action.
389
     *
390
     * @param Application $app
391
     * the Silex application
392
     * @param string $entity
393
     * the current entity
394
     * @param string $id
395
     * the instance id to edit
396
     *
397
     * @return Response
398
     * the HTTP response of this action or 404 on invalid input
399
     */
400 1
    public function edit(Application $app, $entity, $id)
401
    {
402 1
        $crudData = $app['crud']->getData($entity);
403 1
        $instance = $crudData->get($id);
404 1
        if (!$instance) {
405 1
            return $this->getNotFoundPage($app, $app['translator']->trans('crudlex.instanceNotFound'));
406
        }
407
408 1
        return $this->modifyEntity($app, $crudData, $instance, $entity, true);
409
    }
410
411
    /**
412
     * The controller for the "delete" action.
413
     *
414
     * @param Application $app
415
     * the Silex application
416
     * @param string $entity
417
     * the current entity
418
     * @param string $id
419
     * the instance id to delete
420
     *
421
     * @return Response
422
     * redirects to the entity list page or 404 on invalid input
423
     */
424 1
    public function delete(Application $app, $entity, $id)
425
    {
426 1
        $crudData = $app['crud']->getData($entity);
427 1
        $instance = $crudData->get($id);
428 1
        if (!$instance) {
429 1
            return $this->getNotFoundPage($app, $app['translator']->trans('crudlex.instanceNotFound'));
430
        }
431
432 1
        $fileHandler  = new FileHandler($app['crud.filesystem'], $crudData->getDefinition());
433 1
        $filesDeleted = $fileHandler->deleteFiles($crudData, $instance, $entity);
434 1
        $deleted      = $filesDeleted ? $crudData->delete($instance) : AbstractData::DELETION_FAILED_EVENT;
435
436 1
        if ($deleted === AbstractData::DELETION_FAILED_EVENT) {
437 1
            $app['session']->getFlashBag()->add('danger', $app['translator']->trans('crudlex.delete.failed'));
438 1
            return $app->redirect($app['url_generator']->generate('crudShow', ['entity' => $entity, 'id' => $id]));
439 1
        } elseif ($deleted === AbstractData::DELETION_FAILED_STILL_REFERENCED) {
440 1
            $app['session']->getFlashBag()->add('danger', $app['translator']->trans('crudlex.delete.error', [
441 1
                '%label%' => $crudData->getDefinition()->getLabel()
442
            ]));
443 1
            return $app->redirect($app['url_generator']->generate('crudShow', ['entity' => $entity, 'id' => $id]));
444
        }
445
446 1
        $redirectPage       = 'crudList';
447 1
        $redirectParameters = $this->getAfterDeleteRedirectParameters($app['request_stack']->getCurrentRequest(), $entity, $redirectPage);
448
449 1
        $app['session']->getFlashBag()->add('success', $app['translator']->trans('crudlex.delete.success', [
450 1
            '%label%' => $crudData->getDefinition()->getLabel()
451
        ]));
452 1
        return $app->redirect($app['url_generator']->generate($redirectPage, $redirectParameters));
453
    }
454
455
    /**
456
     * The controller for the "render file" action.
457
     *
458
     * @param Application $app
459
     * the Silex application
460
     * @param string $entity
461
     * the current entity
462
     * @param string $id
463
     * the instance id
464
     * @param string $field
465
     * the field of the file to render of the instance
466
     *
467
     * @return Response
468
     * the rendered file
469
     */
470 1
    public function renderFile(Application $app, $entity, $id, $field)
471
    {
472 1
        $crudData   = $app['crud']->getData($entity);
473 1
        $instance   = $crudData->get($id);
474 1
        $definition = $crudData->getDefinition();
475 1
        if (!$instance || $definition->getType($field) != 'file' || !$instance->get($field)) {
476 1
            return $this->getNotFoundPage($app, $app['translator']->trans('crudlex.instanceNotFound'));
477
        }
478 1
        $fileHandler = new FileHandler($app['crud.filesystem'], $definition);
479 1
        return $fileHandler->renderFile($instance, $entity, $field);
480
    }
481
482
    /**
483
     * The controller for the "delete file" action.
484
     *
485
     * @param Application $app
486
     * the Silex application
487
     * @param string $entity
488
     * the current entity
489
     * @param string $id
490
     * the instance id
491
     * @param string $field
492
     * the field of the file to delete of the instance
493
     *
494
     * @return Response
495
     * redirects to the instance details page or 404 on invalid input
496
     */
497 1
    public function deleteFile(Application $app, $entity, $id, $field)
498
    {
499 1
        $crudData = $app['crud']->getData($entity);
500 1
        $instance = $crudData->get($id);
501 1
        if (!$instance) {
502 1
            return $this->getNotFoundPage($app, $app['translator']->trans('crudlex.instanceNotFound'));
503
        }
504 1
        $fileHandler = new FileHandler($app['crud.filesystem'], $crudData->getDefinition());
505 1
        if (!$crudData->getDefinition()->getField($field, 'required', false) && $fileHandler->deleteFile($crudData, $instance, $entity, $field)) {
506 1
            $instance->set($field, '');
507 1
            $crudData->update($instance);
508 1
            $app['session']->getFlashBag()->add('success', $app['translator']->trans('crudlex.file.deleted'));
509
        } else {
510 1
            $app['session']->getFlashBag()->add('danger', $app['translator']->trans('crudlex.file.notDeleted'));
511
        }
512 1
        return $app->redirect($app['url_generator']->generate('crudShow', ['entity' => $entity, 'id' => $id]));
513
    }
514
515
    /**
516
     * The controller for serving static files.
517
     *
518
     * @param Request $request
519
     * the current request
520
     * @param Application $app
521
     * the Silex application
522
     *
523
     * @return Response
524
     * redirects to the instance details page or 404 on invalid input
525
     */
526 1
    public function staticFile(Request $request, Application $app)
527
    {
528 1
        $fileParam = str_replace('..', '', $request->get('file'));
529 1
        $file      = __DIR__.'/../static/'.$fileParam;
530 1
        if (!$fileParam || !file_exists($file)) {
531 1
            return $this->getNotFoundPage($app, $app['translator']->trans('crudlex.resourceNotFound'));
532
        }
533
534 1
        $mimeType = MimeType::detectByFilename($file);
535 1
        $size     = filesize($file);
536
537 1
        $streamedFileResponse = new StreamedFileResponse();
538 1
        $response             = new StreamedResponse($streamedFileResponse->getStreamedFileFunction($file), 200, [
539 1
            'Content-Type' => $mimeType,
540 1
            'Content-Disposition' => 'attachment; filename="'.basename($file).'"',
541 1
            'Content-length' => $size
542
        ]);
543
544 1
        $response->setETag(filemtime($file))->setPublic()->isNotModified($request);
545 1
        $response->send();
546
547 1
        return $response;
548
    }
549
550
    /**
551
     * The controller for setting the locale.
552
     *
553
     * @param Request $request
554
     * the current request
555
     * @param Application $app
556
     * the Silex application
557
     * @param string $locale
558
     * the new locale
559
     *
560
     * @return Response
561
     * redirects to the instance details page or 404 on invalid input
562
     */
563 1
    public function setLocale(Request $request, Application $app, $locale)
564
    {
565
566 1
        if (!in_array($locale, $app['crud']->getLocales())) {
567 1
            return $this->getNotFoundPage($app, 'Locale '.$locale.' not found.');
568
        }
569
570 1
        $manageI18n = $app['crud']->isManageI18n();
571 1
        if ($manageI18n) {
572 1
            $app['session']->set('locale', $locale);
573
        }
574 1
        $redirect = $request->get('redirect');
575 1
        return $app->redirect($redirect);
0 ignored issues
show
Security Cross-Site Scripting introduced by
$redirect can contain request data and is used in output context(s) leading to a potential security vulnerability.

8 paths for user data to reach this point

  1. Path: $this->parameters['HTTP_AUTHORIZATION'] seems to return tainted data, and $authorizationHeader is assigned in ServerBag.php on line 62
  1. $this->parameters['HTTP_AUTHORIZATION'] seems to return tainted data, and $authorizationHeader is assigned
    in vendor/ServerBag.php on line 62
  2. ParameterBag::$parameters is assigned
    in vendor/ServerBag.php on line 77
  3. Tainted property ParameterBag::$parameters is read
    in vendor/ParameterBag.php on line 84
  4. ParameterBag::get() returns tainted data, and $result is assigned
    in vendor/Request.php on line 817
  5. Request::get() returns tainted data, and $redirect is assigned
    in src/CRUDlex/Controller.php on line 574
  2. Path: Read from $_POST, and $_POST is passed to Request::createRequestFromFactory() in Request.php on line 314
  1. Read from $_POST, and $_POST is passed to Request::createRequestFromFactory()
    in vendor/Request.php on line 314
  2. $request is passed to Request::__construct()
    in vendor/Request.php on line 2068
  3. $request is passed to Request::initialize()
    in vendor/Request.php on line 255
  4. $request is passed to ParameterBag::__construct()
    in vendor/Request.php on line 273
  5. ParameterBag::$parameters is assigned
    in vendor/ParameterBag.php on line 31
  6. Tainted property ParameterBag::$parameters is read
    in vendor/ParameterBag.php on line 84
  7. ParameterBag::get() returns tainted data, and $result is assigned
    in vendor/Request.php on line 817
  8. Request::get() returns tainted data, and $redirect is assigned
    in src/CRUDlex/Controller.php on line 574
  3. Path: Read from $_SERVER, and $server is assigned in Request.php on line 304
  1. Read from $_SERVER, and $server is assigned
    in vendor/Request.php on line 304
  2. $server is passed to Request::createRequestFromFactory()
    in vendor/Request.php on line 314
  3. $server is passed to Request::__construct()
    in vendor/Request.php on line 2068
  4. $server is passed to Request::initialize()
    in vendor/Request.php on line 255
  5. $server is passed to ParameterBag::__construct()
    in vendor/Request.php on line 278
  6. ParameterBag::$parameters is assigned
    in vendor/ParameterBag.php on line 31
  7. Tainted property ParameterBag::$parameters is read
    in vendor/ParameterBag.php on line 84
  8. ParameterBag::get() returns tainted data, and $result is assigned
    in vendor/Request.php on line 817
  9. Request::get() returns tainted data, and $redirect is assigned
    in src/CRUDlex/Controller.php on line 574
  4. Path: Fetching key HTTP_CONTENT_LENGTH from $_SERVER, and $server is assigned in Request.php on line 307
  1. Fetching key HTTP_CONTENT_LENGTH from $_SERVER, and $server is assigned
    in vendor/Request.php on line 307
  2. $server is passed to Request::createRequestFromFactory()
    in vendor/Request.php on line 314
  3. $server is passed to Request::__construct()
    in vendor/Request.php on line 2068
  4. $server is passed to Request::initialize()
    in vendor/Request.php on line 255
  5. $server is passed to ParameterBag::__construct()
    in vendor/Request.php on line 278
  6. ParameterBag::$parameters is assigned
    in vendor/ParameterBag.php on line 31
  7. Tainted property ParameterBag::$parameters is read
    in vendor/ParameterBag.php on line 84
  8. ParameterBag::get() returns tainted data, and $result is assigned
    in vendor/Request.php on line 817
  9. Request::get() returns tainted data, and $redirect is assigned
    in src/CRUDlex/Controller.php on line 574
  5. Path: Fetching key HTTP_CONTENT_TYPE from $_SERVER, and $server is assigned in Request.php on line 310
  1. Fetching key HTTP_CONTENT_TYPE from $_SERVER, and $server is assigned
    in vendor/Request.php on line 310
  2. $server is passed to Request::createRequestFromFactory()
    in vendor/Request.php on line 314
  3. $server is passed to Request::__construct()
    in vendor/Request.php on line 2068
  4. $server is passed to Request::initialize()
    in vendor/Request.php on line 255
  5. $server is passed to ParameterBag::__construct()
    in vendor/Request.php on line 278
  6. ParameterBag::$parameters is assigned
    in vendor/ParameterBag.php on line 31
  7. Tainted property ParameterBag::$parameters is read
    in vendor/ParameterBag.php on line 84
  8. ParameterBag::get() returns tainted data, and $result is assigned
    in vendor/Request.php on line 817
  9. Request::get() returns tainted data, and $redirect is assigned
    in src/CRUDlex/Controller.php on line 574
  6. Path: $server['HTTP_HOST'] seems to return tainted data, and $server is assigned in Request.php on line 380
  1. $server['HTTP_HOST'] seems to return tainted data, and $server is assigned
    in vendor/Request.php on line 380
  2. $server is assigned
    in vendor/Request.php on line 428
  3. $server is assigned
    in vendor/Request.php on line 429
  4. $server is passed to Request::createRequestFromFactory()
    in vendor/Request.php on line 431
  5. $server is passed to Request::__construct()
    in vendor/Request.php on line 2068
  6. $server is passed to Request::initialize()
    in vendor/Request.php on line 255
  7. $server is passed to ParameterBag::__construct()
    in vendor/Request.php on line 278
  8. ParameterBag::$parameters is assigned
    in vendor/ParameterBag.php on line 31
  9. Tainted property ParameterBag::$parameters is read
    in vendor/ParameterBag.php on line 84
  10. ParameterBag::get() returns tainted data, and $result is assigned
    in vendor/Request.php on line 817
  11. Request::get() returns tainted data, and $redirect is assigned
    in src/CRUDlex/Controller.php on line 574
  7. Path: $this->parameters['PHP_AUTH_USER'] seems to return tainted data, and $headers is assigned in ServerBag.php on line 43
  1. $this->parameters['PHP_AUTH_USER'] seems to return tainted data, and $headers is assigned
    in vendor/ServerBag.php on line 43
  2. $headers is assigned
    in vendor/ServerBag.php on line 44
  3. ServerBag::getHeaders() returns tainted data, and $this->server->getHeaders() is passed to HeaderBag::__construct()
    in vendor/Request.php on line 279
  4. $values is assigned
    in vendor/HeaderBag.php on line 29
  5. $values is passed to HeaderBag::set()
    in vendor/HeaderBag.php on line 30
  6. $values is passed through array_values(), and $values is assigned
    in vendor/HeaderBag.php on line 142
  7. HeaderBag::$headers is assigned
    in vendor/HeaderBag.php on line 145
  8. Tainted property HeaderBag::$headers is read
    in vendor/HeaderBag.php on line 65
  9. HeaderBag::all() returns tainted data, and $headers is assigned
    in vendor/HeaderBag.php on line 113
  10. HeaderBag::get() returns tainted data, and $requestUri is assigned
    in vendor/Request.php on line 1831
  11. $requestUri is passed to ParameterBag::set()
    in vendor/Request.php on line 1862
  12. ParameterBag::$parameters is assigned
    in vendor/ParameterBag.php on line 95
  13. Tainted property ParameterBag::$parameters is read
    in vendor/ParameterBag.php on line 84
  14. ParameterBag::get() returns tainted data, and $result is assigned
    in vendor/Request.php on line 817
  15. Request::get() returns tainted data, and $redirect is assigned
    in src/CRUDlex/Controller.php on line 574
  8. Path: $this->parameters['PHP_AUTH_PW'] seems to return tainted data, and $headers is assigned in ServerBag.php on line 44
  1. $this->parameters['PHP_AUTH_PW'] seems to return tainted data, and $headers is assigned
    in vendor/ServerBag.php on line 44
  2. ServerBag::getHeaders() returns tainted data, and $this->server->getHeaders() is passed to HeaderBag::__construct()
    in vendor/Request.php on line 279
  3. $values is assigned
    in vendor/HeaderBag.php on line 29
  4. $values is passed to HeaderBag::set()
    in vendor/HeaderBag.php on line 30
  5. $values is passed through array_values(), and $values is assigned
    in vendor/HeaderBag.php on line 142
  6. HeaderBag::$headers is assigned
    in vendor/HeaderBag.php on line 145
  7. Tainted property HeaderBag::$headers is read
    in vendor/HeaderBag.php on line 65
  8. HeaderBag::all() returns tainted data, and $headers is assigned
    in vendor/HeaderBag.php on line 113
  9. HeaderBag::get() returns tainted data, and $requestUri is assigned
    in vendor/Request.php on line 1831
  10. $requestUri is passed to ParameterBag::set()
    in vendor/Request.php on line 1862
  11. ParameterBag::$parameters is assigned
    in vendor/ParameterBag.php on line 95
  12. Tainted property ParameterBag::$parameters is read
    in vendor/ParameterBag.php on line 84
  13. ParameterBag::get() returns tainted data, and $result is assigned
    in vendor/Request.php on line 817
  14. Request::get() returns tainted data, and $redirect is assigned
    in src/CRUDlex/Controller.php on line 574

Used in output context

  1. Application::redirect() uses RedirectResponse::__construct() ($url)
    in vendor/src/Silex/Application.php on line 376
  2. RedirectResponse::__construct() uses RedirectResponse::setTargetUrl() ($url)
    in vendor/RedirectResponse.php on line 39
  3. RedirectResponse::setTargetUrl() uses Response::setContent() ($content)
    in vendor/RedirectResponse.php on line 92
  4. Response::setContent() uses property Response::$content for writing
    in vendor/Response.php on line 391
  5. Property Response::$content is used in echo
    in vendor/Response.php on line 350

Preventing Cross-Site-Scripting Attacks

Cross-Site-Scripting allows an attacker to inject malicious code into your website - in particular Javascript code, and have that code executed with the privileges of a visiting user. This can be used to obtain data, or perform actions on behalf of that visiting user.

In order to prevent this, make sure to escape all user-provided data:

// for HTML
$sanitized = htmlentities($tainted, ENT_QUOTES);

// for URLs
$sanitized = urlencode($tainted);

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
576
    }
577
}
578