Passed
Push — master ( 0e10cd...c1cb3a )
by Tim
01:59
created

Statistics::main()   C

Complexity

Conditions 9
Paths 48

Size

Total Lines 120
Code Lines 88

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 88
nc 48
nop 1
dl 0
loc 120
rs 6.7062
c 0
b 0
f 0

How to fix   Long Method   

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
namespace SimpleSAML\Module\statistics\Controller;
4
5
use Exception;
6
use SimpleSAML\Configuration;
7
use SimpleSAML\HTTP\RunnableResponse;
8
use SimpleSAML\Locale\Translate;
9
use SimpleSAML\Module;
10
use SimpleSAML\Session;
11
use SimpleSAML\Utils\HTTP;
12
use SimpleSAML\XHTML\Template;
13
use Symfony\Component\HttpFoundation\Request;
14
15
/**
16
 * Controller class for the statistics module.
17
 *
18
 * This class serves the statistics views available in the module.
19
 *
20
 * @package SimpleSAML\Module\statistics
21
 */
22
class Statistics
23
{
24
    /** @var \SimpleSAML\Configuration */
25
    protected $config;
26
27
    /** @var \SimpleSAML\Configuration */
28
    protected $moduleConfig;
29
30
    /** @var \SimpleSAML\Session */
31
    protected $session;
32
33
34
    /**
35
     * StatisticsController constructor.
36
     *
37
     * @param \SimpleSAML\Configuration $config The configuration to use.
38
     * @param \SimpleSAML\Session $session The current user session.
39
     */
40
    public function __construct(Configuration $config, Session $session)
41
    {
42
        $this->config = $config;
43
        $this->moduleConfig = Configuration::getConfig('module_statistics.php');
44
        $this->session = $session;
45
    }
46
47
48
    /**
49
     * Display statistics metadata.
50
     *
51
     * @param Request $request The current request.
52
     *
53
     * @return \SimpleSAML\XHTML\Template
54
     */
55
    public function metadata(Request $request): Template
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

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

55
    public function metadata(/** @scrutinizer ignore-unused */ Request $request): Template

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
56
    {
57
        AccessCheck::checkAccess($this->moduleConfig);
0 ignored issues
show
Bug introduced by
The type SimpleSAML\Module\statis...\Controller\AccessCheck was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
58
59
        $aggr = new Aggregator();
0 ignored issues
show
Bug introduced by
The type SimpleSAML\Module\statistics\Controller\Aggregator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
60
        $aggr->loadMetadata();
61
        $metadata = $aggr->getMetadata();
62
63
        if ($metadata !== null) {
64
            if (in_array('lastrun', $metadata, true)) {
65
                $metadata['lastrun'] = date('l jS \of F Y H:i:s', $metadata['lastrun']);
66
            }
67
            if (in_array('notBefore', $metadata, true)) {
68
                $metadata['notBefore'] = date('l jS \of F Y H:i:s', $metadata['notBefore']);
69
            }
70
            if (in_array('memory', $metadata, true)) {
71
                $metadata['memory'] = number_format($metadata['memory'] / (1024 * 1024), 2);
72
            }
73
        }
74
75
        $t = new Template($this->config, 'statistics:statmeta.twig');
76
        $t->data = [
77
            'metadata' => $metadata,
78
        ];
79
80
        return $t;
81
    }
82
83
84
    /**
85
     * Display the main admin page.
86
     *
87
     * @return \SimpleSAML\XHTML\Template
88
     */
89
    public function main(Request $request): Template
90
    {
91
        AccessCheck::checkAccess($this->moduleConfig);
92
93
        /**
94
         * Check input parameters
95
         */
96
        $preferRule = $request->query->get('rule');
97
        $preferRule2 = $request->query->get('rule2');
98
        if ($preferRule2 === '_') {
99
            $preferRule2 = null;
100
        }
101
102
        $preferTime = $request->query->get('time');
103
        $preferTimeRes = $request->query->get('res');
104
        $delimiter = $request->query->get('delimiler');
105
106
        /**
107
         * Create statistics data.
108
         */
109
        $ruleset = new Ruleset($this->moduleConfig);
0 ignored issues
show
Bug introduced by
The type SimpleSAML\Module\statistics\Controller\Ruleset was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
110
        $statrule = $ruleset->getRule($preferRule);
111
        $rule = $statrule->getRuleID();
112
113
        /**
114
         * Prepare template.
115
         */
116
        $t = new Template($this->config, 'statistics:statistics.twig');
117
        $t->data = [
118
            'delimiter' => $delimiter,
119
            'pageid' => 'statistics',
120
            'header' => 'stat',
121
            'available_rules' => $ruleset->availableRulesNames(),
122
            'selected_rule' => $rule,
123
            'selected_rule2' => $preferRule2,
124
        ];
125
126
        try {
127
            $dataset = $statrule->getDataset($preferTimeRes, $preferTime);
128
            $dataset->setDelimiter($delimiter);
129
            $dataset->aggregateSummary();
130
            $dataset->calculateMax();
131
        } catch (Exception $e) {
132
            $t->data['error'] = "No data available";
133
            return $t;
134
        }
135
136
        $delimiter = $dataset->getDelimiter();
137
        $timeres = $dataset->getTimeRes();
138
        $fileslot = $dataset->getFileslot();
139
        $timeNavigation = $statrule->getTimeNavigation($timeres, $preferTime);
140
        $piedata = $dataset->getPieData();
141
        $datasets = [$dataset->getPercentValues()];
142
        $axis = $dataset->getAxis();
143
        $maxes = [$dataset->getMax()];
144
145
        $t->data['selected_rule'] = $rule;
146
        $t->data['selected_time'] = $fileslot;
147
        $t->data['selected_timeres'] = $timeres;
148
        $t->data['post_d'] = $this->getBaseURL($t, 'post', 'd');
149
        if (isset($preferRule2)) {
150
            $statrule = $ruleset->getRule($preferRule2);
151
            try {
152
                $dataset2 = $statrule->getDataset($preferTimeRes, $preferTime);
153
                $dataset2->aggregateSummary();
154
                $dataset2->calculateMax();
155
                $datasets[] = $dataset2->getPercentValues();
156
                $maxes[] = $dataset2->getMax();
157
158
                if ($request->query->get('format') === 'csv') {
159
                    header('Content-type: text/csv');
160
                    header('Content-Disposition: attachment; filename="simplesamlphp-data.csv"');
161
                    $data = $dataset->getDebugData();
162
                    foreach ($data as $de) {
163
                        if (isset($de[1])) {
164
                            echo '"' . $de[0] . '",' . $de[1] . "\n";
165
                        }
166
                    }
167
                    exit;
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return SimpleSAML\XHTML\Template. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
168
                } else {
169
                    $t->data['error'] = 'Export format not supported';
170
                    return $t;
171
                }
172
            } catch (Exception $e) {
173
                $t->data['error'] = "No data available to compare";
174
                return $t;
175
            }
176
        }
177
178
        $dimx = $this->moduleConfig->getValue('dimension.x', 800);
179
        $dimy = $this->moduleConfig->getValue('dimension.y', 350);
180
        $grapher = new Graph\GoogleCharts($dimx, $dimy);
0 ignored issues
show
Bug introduced by
The type SimpleSAML\Module\statis...ller\Graph\GoogleCharts was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
181
        $t->data['imgurl'] = $grapher->show($axis['axis'], $axis['axispos'], $datasets, $maxes);
182
183
        if (!empty($piedata)) {
184
            $t->data['pieimgurl'] = $grapher->showPie($dataset->getDelimiterPresentationPie(), $piedata);
185
        }
186
187
        $t->data['available_rules'] = $ruleset->availableRulesNames();
188
        $t->data['available_times'] = $statrule->availableFileSlots($timeres);
189
        $t->data['available_timeres'] = $statrule->availableTimeRes();
190
        $t->data['available_times_prev'] = $timeNavigation['prev'];
191
        $t->data['available_times_next'] = $timeNavigation['next'];
192
        $t->data['current_rule'] = $t->data['available_rules'][$rule];
193
        $t->data['selected_rule2'] = $preferRule2;
194
        $t->data['selected_delimiter'] = $delimiter;
195
        $t->data['debugdata'] = $dataset->getDebugData();
196
        $t->data['results'] = $dataset->getResults();
197
        $t->data['summaryDataset'] = $dataset->getSummary();
198
        $t->data['topdelimiters'] = $dataset->getTopDelimiters();
199
        $t->data['post_rule'] = $this->getBaseURL($t, 'post', 'rule');
200
        $t->data['post_rule2'] = $this->getBaseURL($t, 'post', 'rule2');
201
        $t->data['post_res'] = $this->getBaseURL($t, 'post', 'res');
202
        $t->data['post_time'] = $this->getBaseURL($t, 'post', 'time');
203
        $t->data['get_times_prev'] = $this->getBaseURL($t, 'get', 'time', $t->data['available_times_prev']);
204
        $t->data['get_times_next'] = $this->getBaseURL($t, 'get', 'time', $t->data['available_times_next']);
205
        $t->data['availdelimiters'] = $dataset->availDelimiters();
206
        $t->data['delimiterPresentation'] = $dataset->getDelimiterPresentation();
207
208
        return $t;
209
    }
210
211
212
    /**
213
     * @param \SimpleSAML\XHTML\Template $t
214
     * @param string $type
215
     * @param string|null $key
216
     * @param string|null $value
217
     * @return string|array
218
     */
219
    private function getBaseURL(Template $t, string $type = 'get', string $key = null, string $value = null)
220
    {
221
        $vars = [
222
            'rule' => $t->data['selected_rule'],
223
            'time' => $t->data['selected_time'],
224
            'res' => $t->data['selected_timeres'],
225
        ];
226
        if (isset($t->data['selected_delimiter'])) {
227
            $vars['d'] = $t->data['selected_delimiter'];
228
        }
229
        if (!empty($t->data['selected_rule2']) && $t->data['selected_rule2'] !== '_') {
230
            $vars['rule2'] = $t->data['selected_rule2'];
231
        }
232
        if (isset($key)) {
233
            if (isset($vars[$key])) {
234
                unset($vars[$key]);
235
            }
236
            if (isset($value)) {
237
                $vars[$key] = $value;
238
            }
239
        }
240
        if ($type === 'get') {
241
            return Module::getModuleURL("statistics/showstats.php") . '?' . http_build_query($vars, '', '&');
242
        }
243
        return $vars;
244
    }
245
}
246