Passed
Push — master ( bb3b01...ed8c75 )
by MusikAnimal
06:02
created

AdminStatsController::adminStatsApiAction()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 0
cts 0
cp 0
rs 8.8571
c 0
b 0
f 0
cc 2
eloc 16
nc 2
nop 2
crap 6
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
     */
55
    public function setUpAdminStats($project, $start = null, $end = null)
56
    {
57
        // Load the database information for the tool.
58
        // $projectData will be a redirect if the project is invalid.
59
        $projectData = $this->validateProject($project);
60
        if ($projectData instanceof RedirectResponse) {
0 ignored issues
show
introduced by
The condition $projectData instanceof ...dation\RedirectResponse can never be true since $projectData is never a sub-type of Symfony\Component\HttpFoundation\RedirectResponse.
Loading history...
61
            return $projectData;
62
        }
63
        $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...
64
65
        list($start, $end) = $this->getUTCFromDateParams($start, $end);
66
67
        $this->adminStats = new AdminStats($this->project, $start, $end);
0 ignored issues
show
Bug introduced by
It seems like $start can also be of type string; however, parameter $start of Xtools\AdminStats::__construct() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

67
        $this->adminStats = new AdminStats($this->project, /** @scrutinizer ignore-type */ $start, $end);
Loading history...
Bug introduced by
It seems like $end can also be of type string; however, parameter $end of Xtools\AdminStats::__construct() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

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

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

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