Passed
Push — master ( 35c320...7deb12 )
by MusikAnimal
04:42
created

RfXVoteCalculatorController::getToolShortname()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 0
cp 0
crap 2
rs 10
c 0
b 0
f 0
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\Bundle\FrameworkBundle\Controller\Controller;
9
use Symfony\Component\CssSelector\Exception\InternalErrorException;
10
use Symfony\Component\Debug\Exception\ContextErrorException;
11
use Symfony\Component\HttpFoundation\Request;
12
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
13
use Xtools\ProjectRepository;
14
use Xtools\PageRepository;
15
use Xtools\RFX;
16
use Xtools\User;
17
18
/**
19
 * Controller for the RfX Vote Calculator.
20
 */
21
class RfXVoteCalculatorController extends Controller
22
{
23
24
    /**
25
     * Get the name of the tool's index route.
26
     * @return string
27
     * @codeCoverageIgnore
28
     */
29
    public function getIndexRoute()
30
    {
31
        return 'RfXVoteCalculator';
32
    }
33
34
    /**
35
     * Renders the index page for RfXVoteCalculator
36
     *
37
     * @Route("/rfxvote", name="RfXVoteCalculator")
38
     * @Route("/rfxvote/", name="RfXVoteCalculatorSlash")
39
     * @Route("/rfxvote/index.php", name="RfXVoteCalculatorIndexPhp")
40
     *
41
     * @return Response
0 ignored issues
show
Bug introduced by
The type AppBundle\Controller\Response 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...
42
     */
43
    public function indexAction()
44
    {
45
        // Grab the request object, grab the values out of it.
46
        $request = Request::createFromGlobals();
47
48
        $projectQuery = $request->query->get('project');
49
        $username = $request->query->get('username');
50
51
        if ($projectQuery != '' && $username != '') {
52
            $routeParams = [ 'project' => $projectQuery, 'username' => $username ];
53
            return $this->redirectToRoute(
54
                'rfxvoteResult',
55
                $routeParams
56
            );
57
        } elseif ($projectQuery != '') {
58
            return $this->redirectToRoute(
59
                'rfxvoteResult',
60
                [
61
                    'project' => $projectQuery
62
                ]
63
            );
64
        }
65
66
        // Instantiate the project if we can, or use the default.
67
        $project = (!empty($projectQuery))
68
            ? ProjectRepository::getProject($projectQuery, $this->container)
69
            : ProjectRepository::getDefaultProject($this->container);
70
71
        return $this->render(
72
            'rfxVoteCalculator/index.html.twig',
73
            [
74
                'xtPageTitle' => 'tool-rfxvote',
75
                'xtSubtitle' => 'tool-rfxvote-desc',
76
                'xtPage' => 'rfxvote',
77
                'project' => $project,
78
            ]
79
        );
80
    }
81
82
    /**
83
     * Result View of RfXVoteCalculator
84
     * @Route("/rfxvote/{project}/{username}", name="rfxvoteResult")
85
     * @param string $project  The project we're working on
86
     * @param string $username Username of the user we're analysing.
87
     * @return Response
88
     * @codeCoverageIgnore
89
     */
90
    public function resultAction($project, $username)
91
    {
92
        $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

92
        $conn = $this->getDoctrine()->getManager('replicas')->/** @scrutinizer ignore-call */ getConnection();
Loading history...
93
94
        $projectData = ProjectRepository::getProject($project, $this->container);
95
        $projectRepo = $projectData->getRepository();
96
        $userData = new User($username);
97
        $pageRepo = new PageRepository();
98
        $pageRepo->setContainer($this->container);
99
100
        $dbName = $projectData->getDatabaseName();
101
102
        $rfxParam = $this->getParameter('rfx');
103
104
        if (!$projectData->exists() || $rfxParam == null) {
105
            $this->addFlash('notice', ['invalid-project', $project]);
0 ignored issues
show
Bug introduced by
array('invalid-project', $project) 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

105
            $this->addFlash('notice', /** @scrutinizer ignore-type */ ['invalid-project', $project]);
Loading history...
106
            return $this->redirectToRoute('rfxvote');
107
        }
108
109
        $namespaces = $projectData->getNamespaces();
110
111
        if (!isset($rfxParam[$projectData->getDomain()])) {
112
            $this->addFlash('notice', ['invalid-project-cant-use', $project]);
113
            return $this->redirectToRoute('rfxvote');
114
        }
115
116
        $pageTypes = $rfxParam[$projectData->getDomain()]['pages'];
117
        $namespace
118
            = $rfxParam[$projectData->getDomain()]['rfx_namespace'] !== null
119
            ? $rfxParam[$projectData->getDomain()]['rfx_namespace'] : 4;
120
121
        $finalData = [];
122
123
        // We should probably figure out a better way to do this...
124
        $ignoredPages = '';
125
126
        if (isset($rfxParam[$projectData->getDomain()]['excluded_title'])) {
127
            $titlesExcluded
128
                = $rfxParam[$projectData->getDomain()]['excluded_title'];
129
            foreach ($titlesExcluded as $ignoredPage) {
130
                $ignoredPages .= "AND p.page_title != \"$ignoredPage\"\r\n";
131
            }
132
        }
133
134
        if (isset($rfxParam[$projectData->getDomain()]['excluded_regex'])) {
135
            $titlesExcluded
136
                = $rfxParam[$projectData->getDomain()]['excluded_regex'];
137
            foreach ($titlesExcluded as $ignoredPage) {
138
                $ignoredPages .= "AND p.page_title NOT LIKE \"%$ignoredPage%\"\r\n";
139
            }
140
        }
141
142
        /**
143
         * Contains the total number of !votes the user made, keyed by the RfX
144
         * type and then the vote type.
145
         * @var array
146
         */
147
        $totals = [];
148
149
        foreach ($pageTypes as $type) {
150
            $type = explode(':', $type, 2)[1];
151
152
            $type = str_replace(' ', '_', $type);
153
154
            $pageTable = $projectRepo->getTableName($dbName, 'page');
155
            $revisionTable
156
                = $projectRepo->getTableName($dbName, 'revision');
157
158
            $sql = "SELECT DISTINCT p.page_namespace, p.page_title
159
                    FROM $pageTable p
160
                    RIGHT JOIN $revisionTable r on p.page_id=r.rev_page
161
                    WHERE p.page_namespace = :namespace
162
                    AND r.rev_user_text = :username
163
                    And p.page_title LIKE \"$type/%\"
164
                    AND p.page_title NOT LIKE \"%$type/$username%\"
165
                    $ignoredPages";
166
167
            $sth = $conn->prepare($sql);
168
            $sth->bindParam('namespace', $namespace);
169
            $sth->bindParam('username', $username);
170
171
            $sth->execute();
172
173
            $titles = [];
174
175
            while ($row = $sth->fetch()) {
176
                $titles[] = $namespaces[$row['page_namespace']] .
177
                    ':' .$row['page_title'];
178
            }
179
180
            // Chunking... it's possible to make a URI too long
181
            $titleArray = array_chunk($titles, 20);
182
183
            foreach ($titleArray as $titlesWorked) {
184
                $pageData = $pageRepo->getPagesWikitext($projectData, $titlesWorked);
185
186
                foreach ($pageData as $title => $text) {
187
                    $type = str_replace('_', ' ', $type);
188
                    $rfx = new RFX(
189
                        $text,
190
                        $rfxParam[$projectData->getDomain()]['sections'],
191
                        $namespaces[2],
192
                        $rfxParam[$projectData->getDomain()]['date_regexp'],
193
                        $username
194
                    );
195
                    $section = $rfx->getUserSectionFound();
196
197
                    if ($section == '') {
198
                        // Skip over ones where the user didn't !vote.
199
                        continue;
200
                    }
201
202
                    if (!isset($totals[$type])) {
203
                        $totals[$type] = [];
204
                    }
205
                    if (!isset($totals[$type][$section])) {
206
                        $totals[$type][$section] = 0;
207
                    }
208
                    if (!isset($totals[$type]['total'])) {
209
                        $totals[$type]['total'] = 0;
210
                    }
211
                    $totals[$type][$section] += 1;
212
                    $totals[$type]['total'] += 1;
213
214
                    // Todo: i18n-ize this
215
                    $finalData[$type][$section][$title]['Support']
216
                        = sizeof($rfx->getSection('support'));
217
                    $finalData[$type][$section][$title]['Oppose']
218
                        = sizeof($rfx->getSection('oppose'));
219
                    $finalData[$type][$section][$title]['Neutral']
220
                        = sizeof($rfx->getSection('neutral'));
221
                    $finalData[$type][$section][$title]['Date']
222
                        = $rfx->getEndDate();
223
                    $finalData[$type][$section][$title]['name']
224
                        = explode('/', $title)[1];
225
226
                    unset($rfx);
227
                }
228
            }
229
        }
230
231
        return $this->render(
232
            'rfxVoteCalculator/result.html.twig',
233
            [
234
                'xtPage' => 'rfxvote',
235
                'xtTitle' => $username,
236
                'user' => $userData,
237
                'project' => $projectData,
238
                'data'=> $finalData,
239
                'totals' => $totals,
240
            ]
241
        );
242
    }
243
}
244