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

AdminStatsController   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 171
Duplicated Lines 0 %

Test Coverage

Coverage 83.33%

Importance

Changes 0
Metric Value
dl 0
loc 171
ccs 5
cts 6
cp 0.8333
rs 10
c 0
b 0
f 0
wmc 11

6 Methods

Rating   Name   Duplication   Size   Complexity  
A resultAction() 0 15 2
A setUpAdminStats() 0 19 2
A adminsGroupsApiAction() 0 13 2
B adminStatsApiAction() 0 27 2
A indexAction() 0 14 2
A getIndexRoute() 0 3 1
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 name of the tool's index route.
39
     * This is also the name of the associated model.
40
     * @return string
41
     * @codeCoverageIgnore
42
     */
43
    public function getIndexRoute()
44
    {
45
        return 'AdminStats';
46
    }
47
48
    /**
49
     * Every action in this controller (other than 'index') calls this first.
50
     * If a response is returned, the calling action is expected to return it.
51
     * @param string $project
52
     * @param string $start
53
     * @param string $end
54
     * @return AdminStats|RedirectResponse
55
     * @codeCoverageIgnore
56
     */
57
    public function setUpAdminStats($project, $start = null, $end = null)
58
    {
59
        // Load the database information for the tool.
60
        // $projectData will be a redirect if the project is invalid.
61
        $projectData = $this->validateProject($project);
62
        if ($projectData instanceof RedirectResponse) {
0 ignored issues
show
introduced by
$projectData is never a sub-type of Symfony\Component\HttpFoundation\RedirectResponse.
Loading history...
63
            return $projectData;
64
        }
65
        $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...
66
67
        list($start, $end) = $this->getUTCFromDateParams($start, $end);
68
69
        $this->adminStats = new AdminStats($this->project, $start, $end);
70
        $adminStatsRepo = new AdminStatsRepository();
71
        $adminStatsRepo->setContainer($this->container);
72
        $this->adminStats->setRepository($adminStatsRepo);
73
74
        // For testing purposes.
75
        return $this->adminStats;
76
    }
77
78
    /**
79
     * Method for rendering the AdminStats Main Form.
80
     * This method redirects if valid parameters are found, making it a
81
     * valid form endpoint as well.
82
     * @Route("/adminstats",           name="AdminStats")
83
     * @Route("/adminstats/",          name="AdminStatsSlash")
84
     * @Route("/adminstats/index.php", name="AdminStatsIndexPhp")
85
     * @param Request $request Generated by Symfony
86
     * @return Route|\Symfony\Component\HttpFoundation\Response
87
     */
88 1
    public function indexAction(Request $request)
89
    {
90 1
        $params = $this->parseQueryParams($request);
91
92
        // Redirect if we have a project. $results may also include start and/or end date.
93 1
        if (isset($params['project'])) {
94
            return $this->redirectToRoute('AdminStatsResult', $params);
95
        }
96
97
        // Otherwise render form.
98 1
        return $this->render('adminStats/index.html.twig', [
99 1
            'xtPage' => 'adminstats',
100
            'xtPageTitle' => 'tool-adminstats',
101
            'xtSubtitle' => 'tool-adminstats-desc',
102
        ]);
103
    }
104
105
    /**
106
     * Method for rendering the AdminStats Results
107
     * @Route(
108
     *   "/adminstats/{project}/{start}/{end}", name="AdminStatsResult",
109
     *   requirements={"start" = "|\d{4}-\d{2}-\d{2}", "end" = "|\d{4}-\d{2}-\d{2}"}
110
     * )
111
     * @param Request $request The HTTP request.
112
     * @param string $project Project to run the results against
113
     * @param string $start   Date to start on.  Must parse by strtotime.
114
     * @param string $end     Date to end on.  Must parse by strtotime.
115
     * @return Route|\Symfony\Component\HttpFoundation\Response
116
     * @todo Move SQL to a model.
117
     * @codeCoverageIgnore
118
     */
119
    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

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

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