Passed
Pull Request — master (#125)
by MusikAnimal
03:53
created

ApiController::namespaces()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 22
Code Lines 12

Duplication

Lines 22
Ratio 100 %

Code Coverage

Tests 10
CRAP Score 2.0491

Importance

Changes 0
Metric Value
cc 2
eloc 12
nc 2
nop 1
dl 22
loc 22
ccs 10
cts 13
cp 0.7692
crap 2.0491
rs 9.2
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file contains only the ApiController class.
4
 */
5
6
namespace AppBundle\Controller;
7
8
use Exception;
9
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
10
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
11
use Symfony\Component\HttpFoundation\Request;
12
use Symfony\Component\HttpFoundation\Response;
13
use Symfony\Component\Debug\Exception\FatalErrorException;
14
use FOS\RestBundle\Controller\Annotations as Rest;
15
use FOS\RestBundle\Controller\FOSRestController;
16
use FOS\RestBundle\View\View;
17
use Xtools\ProjectRepository;
18
use Xtools\UserRepository;
19
use Xtools\Page;
20
use Xtools\PagesRepository;
21
use Xtools\Edit;
22
use DateTime;
23
24
/**
25
 * Serves the external API of XTools.
26
 */
27
class ApiController extends FOSRestController
28
{
29
    /**
30
     * Get domain name, URL, and API URL of the given project.
31
     * @Rest\Get("/api/project/normalize/{project}")
32
     * @param string $project Project database name, URL, or domain name.
33
     * @return View
34
     */
35 View Code Duplication
    public function normalizeProject($project)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
36
    {
37
        $proj = ProjectRepository::getProject($project, $this->container);
38
39
        if (!$proj->exists()) {
40
            return new View(
41
                [
42
                    'error' => "$project is not a valid project",
43
                ],
44
                Response::HTTP_NOT_FOUND
45
            );
46
        }
47
48
        return new View(
49
            [
50
                'domain' => $proj->getDomain(),
51
                'url' => $proj->getUrl(),
52
                'api' => $proj->getApiUrl(),
53
                'database' => $proj->getDatabaseName(),
54
            ],
55
            Response::HTTP_OK
56
        );
57
    }
58
59
    /**
60
     * Get all namespaces of the given project. This endpoint also does the same thing
61
     * as the /project/normalize endpoint, returning other basic info about the project.
62
     * @Rest\Get("/api/project/namespaces/{project}")
63
     * @param string $project The project name.
64
     * @return View
65
     */
66 1 View Code Duplication
    public function namespaces($project)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
67
    {
68 1
        $proj = ProjectRepository::getProject($project, $this->container);
69
70 1
        if (!$proj->exists()) {
71
            return new View(
72
                [
73
                    'error' => "$project is not a valid project",
74
                ],
75
                Response::HTTP_NOT_FOUND
76
            );
77
        }
78
79 1
        return new View(
80
            [
81 1
                'domain' => $proj->getDomain(),
82 1
                'url' => $proj->getUrl(),
83 1
                'api' => $proj->getApiUrl(),
84 1
                'database' => $proj->getDatabaseName(),
85 1
                'namespaces' => $proj->getNamespaces(),
86
            ],
87 1
            Response::HTTP_OK
88
        );
89
    }
90
91
    /**
92
     * Count the number of automated edits the given user has made.
93
     * @Rest\Get(
94
     *   "/api/user/automated_editcount/{project}/{username}/{namespace}/{start}/{end}/{tools}",
95
     *   requirements={"start" = "|\d{4}-\d{2}-\d{2}", "end" = "|\d{4}-\d{2}-\d{2}"}
96
     * )
97
     * @param Request $request The HTTP request.
98
     * @param string $project
99
     * @param string $username
100
     * @param int|string $namespace ID of the namespace, or 'all' for all namespaces
101
     * @param string $start In the format YYYY-MM-DD
102
     * @param string $end In the format YYYY-MM-DD
103
     * @param string $tools Non-blank to show which tools were used and how many times.
104
     */
105
    public function automatedEditCount(
106
        Request $request,
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

106
        /** @scrutinizer ignore-unused */ Request $request,

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...
107
        $project,
108
        $username,
109
        $namespace = 'all',
110
        $start = '',
111
        $end = '',
112
        $tools = ''
113
    ) {
114
        $project = ProjectRepository::getProject($project, $this->container);
115
        $user = UserRepository::getUser($username, $this->container);
116
117
        $res = [
118
            'project' => $project->getDomain(),
119
            'username' => $user->getUsername(),
120
            'total_editcount' => $user->countEdits($project, $namespace, $start, $end),
121
        ];
122
123
        if ($tools != '') {
124
            $tools = $user->getAutomatedCounts($project, $namespace, $start, $end);
125
            $res['automated_editcount'] = 0;
126
            foreach ($tools as $tool) {
127
                $res['automated_editcount'] += $tool['count'];
128
            }
129
            $res['automated_tools'] = $tools;
130
        } else {
131
            $res['automated_editcount'] = $user->countAutomatedEdits($project, $namespace, $start, $end);
132
        }
133
134
        $res['nonautomated_editcount'] = $res['total_editcount'] - $res['automated_editcount'];
135
136
        $view = View::create()->setStatusCode(Response::HTTP_OK);
137
        $view->setData($res);
138
139
        return $view->setFormat('json');
140
    }
141
142
    /**
143
     * Get non-automated edits for the given user.
144
     * @Rest\Get(
145
     *   "/api/user/nonautomated_edits/{project}/{username}/{namespace}/{start}/{end}/{offset}",
146
     *   requirements={
147
     *       "start" = "|\d{4}-\d{2}-\d{2}",
148
     *       "end" = "|\d{4}-\d{2}-\d{2}",
149
     *       "offset" = "\d*"
150
     *   }
151
     * )
152
     * @param Request $request The HTTP request.
153
     * @param string $project
154
     * @param string $username
155
     * @param int|string $namespace ID of the namespace, or 'all' for all namespaces
156
     * @param string $start In the format YYYY-MM-DD
157
     * @param string $end In the format YYYY-MM-DD
158
     * @param int $offset For pagination, offset results by N edits
159
     * @return View
160
     */
161
    public function nonautomatedEdits(
162
        Request $request,
163
        $project,
164
        $username,
165
        $namespace,
166
        $start = '',
167
        $end = '',
168
        $offset = 0
169
    ) {
170
        $twig = $this->container->get('twig');
0 ignored issues
show
Unused Code introduced by
The assignment to $twig is dead and can be removed.
Loading history...
171
        $project = ProjectRepository::getProject($project, $this->container);
172
        $user = UserRepository::getUser($username, $this->container);
173
174
        // Reject if they've made too many edits.
175
        if ($user->hasTooManyEdits($project)) {
176
            if ($request->query->get('format') !== 'html') {
177
                return new View(
178
                    [
179
                        'error' => 'Unable to show any data. User has made over ' .
180
                            $user->maxEdits() . ' edits.',
181
                    ],
182
                    Response::HTTP_FORBIDDEN
183
                );
184
            }
185
186
            $edits = [];
187
        } else {
188
            $edits = $user->getNonautomatedEdits($project, $namespace, $start, $end, $offset);
189
        }
190
191
        $view = View::create()->setStatusCode(Response::HTTP_OK);
192
193
        if ($request->query->get('format') === 'html') {
194
            if ($edits) {
195
                $edits = array_map(function ($attrs) use ($project, $username) {
196
                    $page = $project->getRepository()
197
                        ->getPage($project, $attrs['full_page_title']);
1 ignored issue
show
Bug introduced by
The method getPage() does not exist on Xtools\Repository. It seems like you code against a sub-type of Xtools\Repository such as Xtools\ProjectRepository. ( Ignorable by Annotation )

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

197
                        ->/** @scrutinizer ignore-call */ getPage($project, $attrs['full_page_title']);
Loading history...
198
                    $pageTitles[] = $attrs['full_page_title'];
0 ignored issues
show
Comprehensibility Best Practice introduced by
$pageTitles was never initialized. Although not strictly required by PHP, it is generally a good practice to add $pageTitles = array(); before regardless.
Loading history...
199
                    $attrs['id'] = $attrs['rev_id'];
200
                    $attrs['username'] = $username;
201
                    return new Edit($page, $attrs);
202
                }, $edits);
203
            }
204
205
            $twig = $this->container->get('twig');
206
            $view->setTemplate('api/nonautomated_edits.html.twig');
207
            $view->setTemplateData([
208
                'edits' => $edits,
209
                'project' => $project,
210
                'maxEdits' => $user->maxEdits(),
211
            ]);
212
            $view->setFormat('html');
213
        } else {
214
            $res = [
215
                'project' => $project->getDomain(),
216
                'username' => $user->getUsername(),
217
            ];
218
            if ($namespace != '' && $namespace !== 'all') {
219
                $res['namespace'] = $namespace;
220
            }
221
            if ($start != '') {
222
                $res['start'] = $start;
223
            }
224
            if ($end != '') {
225
                $res['end'] = $end;
226
            }
227
            $res['offset'] = $offset;
228
            $res['nonautomated_edits'] = $edits;
229
230
            $view->setData($res)->setFormat('json');
231
        }
232
233
        return $view;
234
    }
235
}
236