Completed
Pull Request — master (#4481)
by Axel
24:43 queued 19:42
created

IdsLogController::export()   F

Complexity

Conditions 18
Paths 483

Size

Total Lines 94
Code Lines 66

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 18
eloc 66
c 0
b 0
f 0
nc 483
nop 2
dl 0
loc 94
rs 1.418

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula - https://ziku.la/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Zikula\SecurityCenterModule\Controller;
15
16
use InvalidArgumentException;
17
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
18
use Symfony\Component\HttpFoundation\RedirectResponse;
19
use Symfony\Component\HttpFoundation\Request;
20
use Symfony\Component\HttpFoundation\Response;
21
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
22
use Symfony\Component\Routing\Annotation\Route;
23
use Symfony\Component\Routing\RouterInterface;
24
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
25
use Zikula\Bundle\CoreBundle\Controller\AbstractController;
26
use Zikula\Bundle\CoreBundle\Response\PlainResponse;
27
use Zikula\Bundle\FormExtensionBundle\Form\Type\DeletionType;
28
use Zikula\Component\SortableColumns\Column;
29
use Zikula\Component\SortableColumns\SortableColumns;
30
use Zikula\PermissionsModule\Annotation\PermissionCheck;
31
use Zikula\SecurityCenterModule\Entity\Repository\IntrusionRepository;
32
use Zikula\SecurityCenterModule\Form\Type\IdsLogExportType;
33
use Zikula\SecurityCenterModule\Form\Type\IdsLogFilterType;
34
use Zikula\ThemeModule\Engine\Annotation\Theme;
35
36
/**
37
 * Class IdsLogController
38
 *
39
 * @Route("/idslog")
40
 */
41
class IdsLogController extends AbstractController
42
{
43
    /**
44
     * @Route("/view/{page}", methods = {"GET"}, requirements={"page" = "\d+"})
45
     * @PermissionCheck("edit")
46
     * @Theme("admin")
47
     * @Template("@ZikulaSecurityCenterModule/IdsLog/view.html.twig")
48
     *
49
     * Function to view ids log events.
50
     */
51
    public function viewLog(
52
        Request $request,
53
        IntrusionRepository $repository,
54
        RouterInterface $router,
55
        int $page = 1
56
    ): array {
57
        // sorting
58
        $sort = $request->query->get('sort', 'date DESC');
59
        $sort_exp = explode(' ', $sort);
60
        $sortField = $sort_exp[0];
61
        $sortDirection = $sort_exp[1] ?? 'ASC';
62
        $sorting = [$sortField => $sortDirection];
63
64
        // filtering
65
        $defaultFilter = [
66
            'uid' => 0,
67
            'name' => null,
68
            'tag' => null,
69
            'value' => null,
70
            'page' => null,
71
            'ip' => null,
72
            'impact' => null
73
        ];
74
        $filterForm = $this->createForm(IdsLogFilterType::class, $defaultFilter, [
75
            'repository' => $repository
76
        ]);
77
        $filters = $where = [];
78
        $filterForm->handleRequest($request);
79
        if ($filterForm->isSubmitted() && $filterForm->isValid()) {
80
            $filters = $filterForm->getData();
81
            foreach ($filters as $flt_key => $flt_value) {
82
                if (isset($flt_value) && !empty($flt_value)) {
83
                    $where[$flt_key] = $flt_value;
84
                }
85
            }
86
        }
87
        $hasFilters = 0 < count($where);
88
89
        // number of items to show
90
        $pageSize = (int)$this->getVar('pagesize', 25);
91
92
        // get data
93
        $paginator = $repository->getIntrusions($where, $sorting, $page, $pageSize);
94
        $paginator->setRoute('zikulasecuritycentermodule_idslog_view');
95
        $paginator->setRouteParameters(['sort' => $sort, 'filter' => $filters]);
96
97
        $sortableColumns = new SortableColumns($router, 'zikulasecuritycentermodule_idslog_view', 'sort', 'sortdir');
98
        $sortableColumns->addColumns([
99
            new Column('name'),
100
            new Column('tag'),
101
            new Column('value'),
102
            new Column('page'),
103
            new Column('username'),
104
            new Column('ip'),
105
            new Column('impact'),
106
            new Column('date')
107
        ]);
108
        $sortableColumns->setOrderBy($sortableColumns->getColumn($sortField), mb_strtoupper($sortDirection));
109
110
        $templateParameters = [
111
            'filterForm' => $filterForm->createView(),
112
            'hasFilters' => $hasFilters,
113
            'sort' => $sortableColumns,
114
            'paginator' => $paginator
115
        ];
116
117
        return $templateParameters;
118
    }
119
120
    /**
121
     * @Route("/export")
122
     * @PermissionCheck("edit")
123
     * @Theme("admin")
124
     * @Template("@ZikulaSecurityCenterModule/IdsLog/export.html.twig")
125
     *
126
     * Export ids log.
127
     *
128
     * @return array|Response
129
     */
130
    public function export(Request $request, IntrusionRepository $repository)
131
    {
132
        $form = $this->createForm(IdsLogExportType::class, []);
133
        $form->handleRequest($request);
134
        if ($form->isSubmitted() && $form->isValid()) {
135
            if ($form->get('export')->isClicked()) {
0 ignored issues
show
Bug introduced by
The method isClicked() does not exist on Symfony\Component\Form\FormInterface. It seems like you code against a sub-type of Symfony\Component\Form\FormInterface such as Symfony\Component\Form\SubmitButton. ( Ignorable by Annotation )

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

135
            if ($form->get('export')->/** @scrutinizer ignore-call */ isClicked()) {
Loading history...
136
                $formData = $form->getData();
137
138
                // export the titles ?
139
                $exportTitles = isset($formData['titles']) && 1 === $formData['titles'];
140
141
                // name of the exported file
142
                $exportFile = $formData['file'] ?? null;
143
                if (null === $exportFile || '' === $exportFile) {
144
                    $exportFile = 'idslog.csv';
145
                }
146
                if (!mb_strrpos($exportFile, '.csv')) {
147
                    $exportFile .= '.csv';
148
                }
149
150
                // delimeter
151
                $delimiter = $formData['delimiter'] ?? null;
152
                if (null === $delimiter || '' === $delimiter) {
153
                    $delimiter = 1;
154
                }
155
                switch ($delimiter) {
156
                    case 1:
157
                        $delimiter = ',';
158
                        break;
159
                    case 2:
160
                        $delimiter = ';';
161
                        break;
162
                    case 3:
163
                        $delimiter = ':';
164
                        break;
165
                    case 4:
166
                        $delimiter = chr(9);
167
                }
168
169
                $titles = [
170
                    $this->trans('Name'),
171
                    $this->trans('Tag'),
172
                    $this->trans('Value'),
173
                    $this->trans('Page'),
174
                    $this->trans('User Name'),
175
                    $this->trans('IP'),
176
                    $this->trans('Impact'),
177
                    $this->trans('PHPIDS filters used'),
178
                    $this->trans('Date')
179
                ];
180
181
                // get data
182
                $items = $repository->getIntrusions([], ['date' => 'DESC']);
183
184
                $string = $exportTitles ? implode($delimiter, $titles) . PHP_EOL : '';
185
                foreach ($items->getResults() as $item) {
186
                    $dta = $item->toArray();
187
                    $dta['filters'] = unserialize($dta['filters']);
188
                    $filtersUsed = '';
189
                    foreach ($dta['filters'] as $filter) {
190
                        $filtersUsed .= $filter['id'] . ' ';
191
                    }
192
                    $string .=
193
                        $dta['name'] . $delimiter .
194
                        $dta['tag'] . $delimiter .
195
                        htmlspecialchars(str_replace(["\r\n", "\n"], ['', ''], $dta['value']), ENT_COMPAT, 'UTF-8', false) . $delimiter .
196
                        htmlspecialchars($dta['page'], ENT_COMPAT, 'UTF-8', false) . $delimiter .
197
                        $dta['user']['uname'] . $delimiter .
198
                        $dta['ip'] . $delimiter .
199
                        $dta['impact'] . $delimiter .
200
                        $filtersUsed . $delimiter .
201
                        $dta['date']->format('Y-m-d H:i:s') . PHP_EOL;
202
                }
203
204
                // create and export the csv file
205
                $response = new PlainResponse($string);
206
                $disposition = $response->headers->makeDisposition(
207
                    ResponseHeaderBag::DISPOSITION_ATTACHMENT,
208
                    $exportFile
209
                );
210
                $response->headers->set('Content-Disposition', $disposition);
211
                $response->headers->set('Content-Type', 'text/csv');
212
213
                return $response;
214
            }
215
            if ($form->get('cancel')->isClicked()) {
216
                $this->addFlash('status', 'Operation cancelled.');
217
218
                return $this->redirectToRoute('zikulasecuritycentermodule_idslog_view');
219
            }
220
        }
221
222
        return [
223
            'form' => $form->createView()
224
        ];
225
    }
226
227
    /**
228
     * @Route("/purge")
229
     * @PermissionCheck("delete")
230
     * @Theme("admin")
231
     * @Template("@ZikulaSecurityCenterModule/IdsLog/purge.html.twig")
232
     *
233
     * Purge ids log.
234
     *
235
     * @return array|RedirectResponse
236
     */
237
    public function purge(Request $request, IntrusionRepository $repository)
238
    {
239
        $form = $this->createForm(DeletionType::class);
240
        $form->handleRequest($request);
241
        if ($form->isSubmitted() && $form->isValid()) {
242
            if ($form->get('delete')->isClicked()) {
243
                // delete all entries
244
                $repository->truncateTable();
245
246
                $this->addFlash('status', 'Done! Purged IDS log.');
247
            } elseif ($form->get('cancel')->isClicked()) {
248
                $this->addFlash('status', 'Operation cancelled.');
249
            }
250
251
            return $this->redirectToRoute('zikulasecuritycentermodule_idslog_view');
252
        }
253
254
        return [
255
            'form' => $form->createView()
256
        ];
257
    }
258
259
    /**
260
     * @Route("/deleteentry")
261
     * @PermissionCheck("delete")
262
     *
263
     * Delete an ids log entry.
264
     *
265
     * @throws AccessDeniedException Thrown if the CSRF token is invalid
266
     * @throws InvalidArgumentException Thrown if the object id is not numeric or if
267
     */
268
    public function deleteEntry(Request $request, IntrusionRepository $repository): RedirectResponse
269
    {
270
        if (!$this->isCsrfTokenValid('delete-idsentry', $request->query->get('token'))) {
271
            throw new AccessDeniedException();
272
        }
273
274
        $id = $request->query->getInt('id', 0);
275
        $intrusion = $repository->find($id);
276
        if (!$intrusion) {
277
            $this->addFlash('error', $this->trans('Error! Invalid %identifier% received.', ['%identifier%' => "object ID [${id}]"]));
278
        } else {
279
            // delete object
280
            $this->getDoctrine()->getManager()->remove($intrusion);
281
            $this->getDoctrine()->getManager()->flush();
282
        }
283
284
        return $this->redirectToRoute('zikulasecuritycentermodule_idslog_view');
285
    }
286
}
287