Passed
Push — master ( 9a481f...a0a42c )
by MusikAnimal
05:51
created

AdminStatsController   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 164
Duplicated Lines 0 %

Test Coverage

Coverage 25%

Importance

Changes 0
Metric Value
dl 0
loc 164
ccs 4
cts 16
cp 0.25
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 12 2
A getToolShortname() 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\Response;
14
use Symfony\Component\HttpFoundation\RedirectResponse;
15
use Symfony\Component\HttpFoundation\JsonResponse;
16
use Xtools\AdminStats;
17
use Xtools\AdminStatsRepository;
18
use Xtools\ProjectRepository;
19
20
/**
21
 * Class AdminStatsController
22
 *
23
 * @category AdminStats
24
 * @package  AppBundle\Controller
25
 * @author   XTools Team <[email protected]>
26
 * @license  GPL 3.0
27
 */
28
class AdminStatsController extends XtoolsController
29
{
30
    /** @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...
31
    protected $project;
32
33
    /** @var AdminStats The admin stats instance that does all the work. */
34
    protected $adminStats;
35
36
    /**
37
     * Get the tool's shortname.
38
     * @return string
39
     * @codeCoverageIgnore
40
     */
41
    public function getToolShortname()
42
    {
43
        return 'adminstats';
44
    }
45
46
    /**
47
     * Every action in this controller (other than 'index') calls this first.
48
     * If a response is returned, the calling action is expected to return it.
49
     * @param string $project
50
     * @param string $start
51
     * @param string $end
52
     * @return AdminStats|RedirectResponse
53
     */
54
    public function setUpAdminStats($project, $start = null, $end = null)
55
    {
56
        // Load the database information for the tool.
57
        // $projectData will be a redirect if the project is invalid.
58
        $projectData = $this->validateProject($project);
59
        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...
60
            return $projectData;
61
        }
62
        $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...
63
64
        list($start, $end) = $this->getUTCFromDateParams($start, $end);
65
66
        $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

66
        $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

66
        $this->adminStats = new AdminStats($this->project, $start, /** @scrutinizer ignore-type */ $end);
Loading history...
67
        $adminStatsRepo = new AdminStatsRepository();
68
        $adminStatsRepo->setContainer($this->container);
69
        $this->adminStats->setRepository($adminStatsRepo);
70
71
        // For testing purposes.
72
        return $this->adminStats;
73
    }
74
75
    /**
76
     * Method for rendering the AdminStats Main Form.
77
     * This method redirects if valid parameters are found, making it a
78
     * valid form endpoint as well.
79
     * @Route("/adminstats",           name="adminstats")
80
     * @Route("/adminstats/",          name="AdminStatsSlash")
81
     * @Route("/adminstats/index.php", name="AdminStatsIndexPhp")
82
     * @return Route|\Symfony\Component\HttpFoundation\Response
83
     */
84 1
    public function indexAction()
85
    {
86
        // Redirect if we have a project. $results may also include start and/or end date.
87 1
        if (isset($this->params['project'])) {
88
            return $this->redirectToRoute('AdminStatsResult', $this->params);
89
        }
90
91
        // Otherwise render form.
92 1
        return $this->render('adminStats/index.html.twig', [
93 1
            'xtPage' => 'adminstats',
94
            'xtPageTitle' => 'tool-adminstats',
95
            'xtSubtitle' => 'tool-adminstats-desc',
96
        ]);
97
    }
98
99
    /**
100
     * Method for rendering the AdminStats Results
101
     * @Route(
102
     *   "/adminstats/{project}/{start}/{end}", name="AdminStatsResult",
103
     *   requirements={"start" = "|\d{4}-\d{2}-\d{2}", "end" = "|\d{4}-\d{2}-\d{2}"}
104
     * )
105
     * @param string $project Project to run the results against
106
     * @param string $start   Date to start on.  Must parse by strtotime.
107
     * @param string $end     Date to end on.  Must parse by strtotime.
108
     * @return Response|RedirectResponse
109
     * @codeCoverageIgnore
110
     */
111
    public function resultAction($project, $start = null, $end = null)
112
    {
113
        $ret = $this->setUpAdminStats($project, $start, $end);
114
        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...
115
            return $ret;
116
        }
117
118
        $this->adminStats->prepareStats();
119
120
        // Render the result!
121
        return $this->render('adminStats/result.html.twig', [
122
            'xtPage' => 'adminstats',
123
            'xtTitle' => $this->project->getDomain(),
124
            'project' => $this->project,
125
            'as' => $this->adminStats,
126
        ]);
127
    }
128
129
    /************************ API endpoints ************************/
130
131
    /**
132
     * Get users of the project that are capable of making 'admin actions',
133
     * keyed by user name with a list of the relevant user groups as the values.
134
     * @Route("/api/project/admins_groups/{project}", name="ProjectApiAdminsGroups")
135
     * @param string $project Project domain or database name.
136
     * @return Response
137
     * @codeCoverageIgnore
138
     */
139
    public function adminsGroupsApiAction($project)
140
    {
141
        $this->recordApiUsage('project/admins_groups');
142
143
        $ret = $this->setUpAdminStats($project);
144
        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...
145
            // FIXME: needs to render as JSON, fetching the message from the FlashBag.
146
            return $ret;
147
        }
148
149
        return new JsonResponse(
150
            $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

150
            $this->adminStats->getAdminsAndGroups(/** @scrutinizer ignore-type */ false),
Loading history...
151
            Response::HTTP_OK
152
        );
153
    }
154
155
    /**
156
     * Get users of the project that are capable of making 'admin actions',
157
     * along with various stats about which actions they took. Time period is limited
158
     * to one month.
159
     * @Route("/api/project/adminstats/{project}/{days}", name="ProjectApiAdminStats")
160
     * @param string $project Project domain or database name.
161
     * @param int $days Number of days from present to grab data for. Maximum 30.
162
     * @return Response
163
     * @codeCoverageIgnore
164
     */
165
    public function adminStatsApiAction($project, $days = 30)
166
    {
167
        $this->recordApiUsage('project/adminstats');
168
169
        // Maximum 30 days.
170
        $days = min((int) $days, 30);
171
        $start = date('Y-m-d', strtotime("-$days days"));
172
        $end = date('Y-m-d');
173
174
        $ret = $this->setUpAdminStats($project, $start, $end);
175
        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...
176
            // FIXME: needs to render as JSON, fetching the message from the FlashBag.
177
            return $ret;
178
        }
179
180
        $this->adminStats->prepareStats(false);
181
182
        $response = [
183
            'project' => $this->project->getDomain(),
184
            'start' => $this->adminStats->getStart(),
185
            'end' => $this->adminStats->getEnd(),
186
            'users' => $this->adminStats->getStats(false),
187
        ];
188
189
        return new JsonResponse(
190
            $response,
191
            Response::HTTP_OK
192
        );
193
    }
194
}
195