Passed
Push — master ( dad31f...0bbc99 )
by MusikAnimal
06:39 queued 01:28
created

AdminStatsController::setUpAdminStats()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 10
nc 2
nop 3
dl 0
loc 19
ccs 0
cts 0
cp 0
crap 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file contains the code that powers the AdminStats page of XTools.
5
 *
6
 * @version 1.5.1
7
 */
8
9
namespace AppBundle\Controller;
10
11
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
12
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\HttpFoundation\Response;
15
use Symfony\Component\HttpFoundation\RedirectResponse;
16
use Symfony\Component\HttpFoundation\JsonResponse;
17
use Xtools\AdminStats;
18
use Xtools\AdminStatsRepository;
19
use Xtools\ProjectRepository;
20
21
/**
22
 * Class AdminStatsController
23
 *
24
 * @category AdminStats
25
 * @package  AppBundle\Controller
26
 * @author   XTools Team <[email protected]>
27
 * @license  GPL 3.0
28
 */
29
class AdminStatsController extends XtoolsController
30
{
31
    /** @var Project The project being queried. */
0 ignored issues
show
Bug introduced by
The type AppBundle\Controller\Project 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...
32
    protected $project;
33
34
    /** @var AdminStats The admin stats instance that does all the work. */
35
    protected $adminStats;
36
37
    /**
38
     * Get the tool's shortname.
39
     * @return string
40
     * @codeCoverageIgnore
41
     */
42
    public function getToolShortname()
43
    {
44
        return 'adminstats';
45
    }
46
47
    /**
48
     * Every action in this controller (other than 'index') calls this first.
49
     * If a response is returned, the calling action is expected to return it.
50
     * @param string $project
51
     * @param string $start
52
     * @param string $end
53
     * @return AdminStats|RedirectResponse
54
     * @codeCoverageIgnore
55
     */
56
    public function setUpAdminStats($project, $start = null, $end = null)
57
    {
58
        // Load the database information for the tool.
59
        // $projectData will be a redirect if the project is invalid.
60
        $projectData = $this->validateProject($project);
61
        if ($projectData instanceof RedirectResponse) {
0 ignored issues
show
introduced by
$projectData is never a sub-type of Symfony\Component\HttpFoundation\RedirectResponse.
Loading history...
62
            return $projectData;
63
        }
64
        $this->project = $projectData;
0 ignored issues
show
Documentation Bug introduced by
It seems like $projectData of type Xtools\Project is incompatible with the declared type AppBundle\Controller\Project of property $project.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
65
66
        list($start, $end) = $this->getUTCFromDateParams($start, $end);
67
68
        $this->adminStats = new AdminStats($this->project, $start, $end);
69
        $adminStatsRepo = new AdminStatsRepository();
70
        $adminStatsRepo->setContainer($this->container);
71
        $this->adminStats->setRepository($adminStatsRepo);
72
73
        // For testing purposes.
74
        return $this->adminStats;
75
    }
76
77
    /**
78
     * Method for rendering the AdminStats Main Form.
79
     * This method redirects if valid parameters are found, making it a
80
     * valid form endpoint as well.
81
     *
82
     * @param Request $request Generated by Symfony
83
     *
84
     * @Route("/adminstats",           name="adminstats")
85
     * @Route("/adminstats/",          name="AdminStatsSlash")
86
     * @Route("/adminstats/index.php", name="AdminStatsIndexPhp")
87
     *
88
     * @return Route|\Symfony\Component\HttpFoundation\Response
89
     */
90 1
    public function indexAction(Request $request)
91
    {
92 1
        $params = $this->parseQueryParams($request);
93
94
        // Redirect if we have a project. $results may also include start and/or end date.
95 1
        if (isset($params['project'])) {
96
            return $this->redirectToRoute('AdminStatsResult', $params);
97
        }
98
99
        // Otherwise render form.
100 1
        return $this->render('adminStats/index.html.twig', [
101 1
            'xtPage' => 'adminstats',
102
            'xtPageTitle' => 'tool-adminstats',
103
            'xtSubtitle' => 'tool-adminstats-desc',
104
        ]);
105
    }
106
107
    /**
108
     * Method for rendering the AdminStats Results
109
     *
110
     * @param Request $request The HTTP request.
111
     * @param string $project Project to run the results against
112
     * @param string $start   Date to start on.  Must parse by strtotime.
113
     * @param string $end     Date to end on.  Must parse by strtotime.
114
     *
115
     * @Route(
116
     *   "/adminstats/{project}/{start}/{end}", name="AdminStatsResult",
117
     *   requirements={"start" = "|\d{4}-\d{2}-\d{2}", "end" = "|\d{4}-\d{2}-\d{2}"}
118
     * )
119
     *
120
     * @return Route|\Symfony\Component\HttpFoundation\Response
121
     * @todo Move SQL to a model.
122
     * @codeCoverageIgnore
123
     */
124
    public function resultAction(Request $request, $project, $start = null, $end = null)
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

124
    public function resultAction(/** @scrutinizer ignore-unused */ Request $request, $project, $start = null, $end = null)

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...
125
    {
126
        $ret = $this->setUpAdminStats($project, $start, $end);
127
        if ($ret instanceof RedirectResponse) {
0 ignored issues
show
introduced by
$ret is never a sub-type of Symfony\Component\HttpFoundation\RedirectResponse.
Loading history...
128
            return $ret;
129
        }
130
131
        $this->adminStats->prepareStats();
132
133
        // Render the result!
134
        return $this->render('adminStats/result.html.twig', [
135
            'xtPage' => 'adminstats',
136
            'xtTitle' => $this->project->getDomain(),
137
            'project' => $this->project,
138
            'as' => $this->adminStats,
139
        ]);
140
    }
141
142
    /************************ API endpoints ************************/
143
144
    /**
145
     * Get users of the project that are capable of making 'admin actions',
146
     * keyed by user name with a list of the relevant user groups as the values.
147
     * @Route("/api/project/admins_groups/{project}", name="ProjectApiAdminsGroups")
148
     * @param string $project Project domain or database name.
149
     * @return Response
150
     * @codeCoverageIgnore
151
     */
152
    public function adminsGroupsApiAction($project)
153
    {
154
        $this->recordApiUsage('project/admins_groups');
155
156
        $ret = $this->setUpAdminStats($project);
157
        if ($ret instanceof RedirectResponse) {
0 ignored issues
show
introduced by
$ret is never a sub-type of Symfony\Component\HttpFoundation\RedirectResponse.
Loading history...
158
            // FIXME: needs to render as JSON, fetching the message from the FlashBag.
159
            return $ret;
160
        }
161
162
        return new JsonResponse(
163
            $this->adminStats->getAdminsAndGroups(false),
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $abbreviate of Xtools\AdminStats::getAdminsAndGroups(). ( Ignorable by Annotation )

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

163
            $this->adminStats->getAdminsAndGroups(/** @scrutinizer ignore-type */ false),
Loading history...
164
            Response::HTTP_OK
165
        );
166
    }
167
168
    /**
169
     * Get users of the project that are capable of making 'admin actions',
170
     * along with various stats about which actions they took. Time period is limited
171
     * to one month.
172
     * @Route("/api/project/adminstats/{project}/{days}", name="ProjectApiAdminStats")
173
     * @param string $project Project domain or database name.
174
     * @param int $days Number of days from present to grab data for. Maximum 30.
175
     * @return Response
176
     * @codeCoverageIgnore
177
     */
178
    public function adminStatsApiAction($project, $days = 30)
179
    {
180
        $this->recordApiUsage('project/adminstats');
181
182
        // Maximum 30 days.
183
        $days = min((int) $days, 30);
184
        $start = date('Y-m-d', strtotime("-$days days"));
185
        $end = date('Y-m-d');
186
187
        $ret = $this->setUpAdminStats($project, $start, $end);
188
        if ($ret instanceof RedirectResponse) {
0 ignored issues
show
introduced by
$ret is never a sub-type of Symfony\Component\HttpFoundation\RedirectResponse.
Loading history...
189
            // FIXME: needs to render as JSON, fetching the message from the FlashBag.
190
            return $ret;
191
        }
192
193
        $this->adminStats->prepareStats(false);
194
195
        $response = [
196
            'project' => $this->project->getDomain(),
197
            'start' => $start,
198
            'end' => $end,
199
            'users' => $this->adminStats->getStats(false),
200
        ];
201
202
        return new JsonResponse(
203
            $response,
204
            Response::HTTP_OK
205
        );
206
    }
207
}
208