Passed
Push — master ( e6ce91...429907 )
by MusikAnimal
04:46
created

RfXVoteCalculatorController::resultAction()   D

Complexity

Conditions 15
Paths 185

Size

Total Lines 143
Code Lines 87

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 240

Importance

Changes 0
Metric Value
cc 15
eloc 87
nc 185
nop 0
dl 0
loc 143
ccs 0
cts 0
cp 0
crap 240
rs 4.4503
c 0
b 0
f 0

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
 * This file contains the code that powers the RfX Vote Calculator page of XTools.
4
 */
5
6
namespace AppBundle\Controller;
7
8
use Symfony\Component\HttpFoundation\Response;
9
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
10
use Xtools\PageRepository;
11
use Xtools\RFX;
12
13
/**
14
 * Controller for the RfX Vote Calculator.
15
 */
16
class RfXVoteCalculatorController extends XtoolsController
17
{
18
    /**
19
     * Get the name of the tool's index route.
20
     * @return string
21
     * @codeCoverageIgnore
22
     */
23
    public function getIndexRoute()
24
    {
25
        return 'RfXVoteCalculator';
26
    }
27
28
    /**
29
     * Renders the index page for RfXVoteCalculator
30
     *
31
     * @Route("/rfxvote", name="RfXVoteCalculator")
32
     * @Route("/rfxvote/", name="RfXVoteCalculatorSlash")
33
     * @Route("/rfxvote/index.php", name="RfXVoteCalculatorIndexPhp")
34
     * @return Response
35
     */
36
    public function indexAction()
37
    {
38
        // Redirect if at minimum project, username and categories are provided.
39
        if (isset($this->params['project']) && isset($this->params['username'])) {
40
            return $this->redirectToRoute('RfXVoteResult', $this->params);
41
        }
42
43
        return $this->render(
44
            'rfxVoteCalculator/index.html.twig',
45
            [
46
                'xtPageTitle' => 'tool-rfxvote',
47
                'xtSubtitle' => 'tool-rfxvote-desc',
48
                'xtPage' => 'rfxvote',
49
                'project' => $this->project,
50
            ]
51
        );
52
    }
53
54
    /**
55
     * Result View of RfXVoteCalculator
56
     * @Route("/rfxvote/{project}/{username}", name="RfXVoteResult")
57
     * @return Response
58
     * @codeCoverageIgnore
59
     */
60
    public function resultAction()
61
    {
62
        $conn = $this->getDoctrine()->getManager('replicas')->getConnection();
0 ignored issues
show
Bug introduced by
The method getConnection() does not exist on Doctrine\Common\Persistence\ObjectManager. It seems like you code against a sub-type of said class. However, the method does not exist in Doctrine\Common\Persistence\ObjectManagerDecorator. Are you sure you never get one of those? ( Ignorable by Annotation )

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

62
        $conn = $this->getDoctrine()->getManager('replicas')->/** @scrutinizer ignore-call */ getConnection();
Loading history...
63
64
        $projectRepo = $this->project->getRepository();
65
        $pageRepo = new PageRepository();
66
        $pageRepo->setContainer($this->container);
67
68
        $dbName = $this->project->getDatabaseName();
69
70
        $rfxParam = $this->getParameter('rfx');
71
72
        $namespaces = $this->project->getNamespaces();
73
74
        if (!isset($rfxParam[$this->project->getDomain()])) {
75
            $this->addFlash('notice', ['invalid-project-cant-use', $this->project->getDomain()]);
0 ignored issues
show
Bug introduced by
array('invalid-project-c...->project->getDomain()) of type array<integer,string> is incompatible with the type string expected by parameter $message of Symfony\Bundle\Framework...\Controller::addFlash(). ( Ignorable by Annotation )

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

75
            $this->addFlash('notice', /** @scrutinizer ignore-type */ ['invalid-project-cant-use', $this->project->getDomain()]);
Loading history...
76
            return $this->redirectToRoute('RfXVoteCalculator');
77
        }
78
79
        $pageTypes = $rfxParam[$this->project->getDomain()]['pages'];
80
        $namespace = $rfxParam[$this->project->getDomain()]['rfx_namespace'] !== null
81
            ? $rfxParam[$this->project->getDomain()]['rfx_namespace']
82
            : 4;
83
84
        $finalData = [];
85
86
        // We should probably figure out a better way to do this...
87
        $ignoredPages = '';
88
89
        if (isset($rfxParam[$this->project->getDomain()]['excluded_title'])) {
90
            $titlesExcluded
91
                = $rfxParam[$this->project->getDomain()]['excluded_title'];
92
            foreach ($titlesExcluded as $ignoredPage) {
93
                $ignoredPages .= "AND p.page_title != \"$ignoredPage\"\r\n";
94
            }
95
        }
96
97
        if (isset($rfxParam[$this->project->getDomain()]['excluded_regex'])) {
98
            $titlesExcluded
99
                = $rfxParam[$this->project->getDomain()]['excluded_regex'];
100
            foreach ($titlesExcluded as $ignoredPage) {
101
                $ignoredPages .= "AND p.page_title NOT LIKE \"%$ignoredPage%\"\r\n";
102
            }
103
        }
104
105
        /**
106
         * Contains the total number of !votes the user made, keyed by the RfX
107
         * type and then the vote type.
108
         * @var array
109
         */
110
        $totals = [];
111
112
        foreach ($pageTypes as $type) {
113
            $type = explode(':', $type, 2)[1];
114
115
            $type = str_replace(' ', '_', $type);
116
117
            $pageTable = $projectRepo->getTableName($dbName, 'page');
118
            $revisionTable = $projectRepo->getTableName($dbName, 'revision');
119
            $username = $this->user->getUsername();
120
121
            $sql = "SELECT DISTINCT p.page_namespace, p.page_title
122
                    FROM $pageTable p
123
                    RIGHT JOIN $revisionTable r on p.page_id=r.rev_page
124
                    WHERE p.page_namespace = :namespace
125
                    AND r.rev_user_text = :username
126
                    And p.page_title LIKE \"$type/%\"
127
                    AND p.page_title NOT LIKE \"%$type/$username%\"
128
                    $ignoredPages";
129
130
            $sth = $conn->prepare($sql);
131
            $sth->bindParam('namespace', $namespace);
132
            $sth->bindParam('username', $username);
133
134
            $sth->execute();
135
136
            $titles = [];
137
138
            while ($row = $sth->fetch()) {
139
                $titles[] = $namespaces[$row['page_namespace']] .
140
                    ':' .$row['page_title'];
141
            }
142
143
            // Chunking... it's possible to make a URI too long
144
            $titleArray = array_chunk($titles, 20);
145
146
            foreach ($titleArray as $titlesWorked) {
147
                $pageData = $pageRepo->getPagesWikitext($this->project, $titlesWorked);
148
149
                foreach ($pageData as $title => $text) {
150
                    $type = str_replace('_', ' ', $type);
151
                    $rfx = new RFX(
152
                        $text,
153
                        $rfxParam[$this->project->getDomain()]['sections'],
154
                        $namespaces[2],
155
                        $rfxParam[$this->project->getDomain()]['date_regexp'],
156
                        $username
157
                    );
158
                    $section = $rfx->getUserSectionFound();
159
160
                    if ($section == '') {
161
                        // Skip over ones where the user didn't !vote.
162
                        continue;
163
                    }
164
165
                    if (!isset($totals[$type])) {
166
                        $totals[$type] = [];
167
                    }
168
                    if (!isset($totals[$type][$section])) {
169
                        $totals[$type][$section] = 0;
170
                    }
171
                    if (!isset($totals[$type]['total'])) {
172
                        $totals[$type]['total'] = 0;
173
                    }
174
                    $totals[$type][$section] += 1;
175
                    $totals[$type]['total'] += 1;
176
177
                    // Todo: i18n-ize this
178
                    $finalData[$type][$section][$title]['Support']
179
                        = sizeof($rfx->getSection('support'));
180
                    $finalData[$type][$section][$title]['Oppose']
181
                        = sizeof($rfx->getSection('oppose'));
182
                    $finalData[$type][$section][$title]['Neutral']
183
                        = sizeof($rfx->getSection('neutral'));
184
                    $finalData[$type][$section][$title]['Date']
185
                        = $rfx->getEndDate();
186
                    $finalData[$type][$section][$title]['name']
187
                        = explode('/', $title)[1];
188
189
                    unset($rfx);
190
                }
191
            }
192
        }
193
194
        return $this->render(
195
            'rfxVoteCalculator/result.html.twig',
196
            [
197
                'xtPage' => 'rfxvote',
198
                'xtTitle' => $this->user->getUsername(),
199
                'user' => $this->user,
200
                'project' => $this->project,
201
                'data'=> $finalData,
202
                'totals' => $totals,
203
            ]
204
        );
205
    }
206
}
207