ProjectControllerJson::connect()   A
last analyzed

Complexity

Conditions 4
Paths 12

Size

Total Lines 60
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 33
CRAP Score 4.0029

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 4
eloc 33
c 2
b 0
f 0
nc 12
nop 3
dl 0
loc 60
ccs 33
cts 35
cp 0.9429
crap 4.0029
rs 9.392

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace App\Controller;
4
5
use Exception;
6
use Symfony\Bundle\FrameworkBundle\Console\Application;
7
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
8
use Symfony\Component\Console\Exception\CommandNotFoundException;
9
use Symfony\Component\Console\Input\ArrayInput;
10
use Symfony\Component\Console\Output\BufferedOutput;
11
use Symfony\Component\Console\Output\NullOutput;
12
use Symfony\Component\HttpFoundation\JsonResponse;
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\HttpFoundation\Response;
15
use Symfony\Component\HttpFoundation\Session\SessionInterface;
16
use Symfony\Component\HttpKernel\KernelInterface;
17
use Symfony\Component\Routing\Annotation\Route;
18
use Doctrine\Persistence\ManagerRegistry;
19
use Doctrine\ORM\EntityManagerInterface;
20
use App\Adventure\Log;
21
use App\Entity\Game\Connection;
22
use App\Entity\Game\Item;
23
use App\Entity\Game\Location;
24
use App\Repository\Game\ConnectionRepository;
25
use App\Repository\Game\ItemRepository;
26
use App\Repository\Game\LocationRepository;
27
28
class ProjectControllerJson extends AbstractController
29
{
30 2
    #[Route("/proj/api/locations", name: "proj_api_locations")]
31
    public function locations(LocationRepository $locationRepository): Response
32
    {
33 2
        $locations = $locationRepository->findAll();
34
35 2
        if (empty($locations)) {
36 1
            return $this->json(['error' => 'No locations found'], Response::HTTP_NOT_FOUND);
37
        }
38
39 1
        $response = $this->json($locations);
40 1
        $response->setEncodingOptions(
41 1
            $response->getEncodingOptions() | JSON_PRETTY_PRINT,
42 1
        );
43 1
        return $response;
44
    }
45
46 2
    #[Route("/proj/api/locations/{id}", name: "proj_api_locations_by_id")]
47
    public function locationById(int $id, LocationRepository $locationRepository): JsonResponse
48
    {
49 2
        $location = $locationRepository->find($id);
50
51 2
        if (!$location) {
52 1
            return $this->json(['error' => "No location found with ID {$id}"], Response::HTTP_NOT_FOUND);
53
        }
54
55 1
        $response = $this->json($location);
56 1
        $response->setEncodingOptions(
57 1
            $response->getEncodingOptions() | JSON_PRETTY_PRINT,
58 1
        );
59 1
        return $response;
60
    }
61
62 2
    #[Route("/proj/api/items", name: "proj_api_items")]
63
    public function items(ItemRepository $itemRepository): Response
64
    {
65 2
        $items = $itemRepository->findAll();
66
67 2
        if (empty($items)) {
68 1
            return $this->json(['error' => 'No items found'], Response::HTTP_NOT_FOUND);
69
        }
70
71 1
        $response = $this->json($items);
72 1
        $response->setEncodingOptions(
73 1
            $response->getEncodingOptions() | JSON_PRETTY_PRINT,
74 1
        );
75 1
        return $response;
76
    }
77
78 2
    #[Route("/proj/api/items/{id}", name: "proj_api_items_by_id")]
79
    public function itemById(int $id, ItemRepository $itemRepository): JsonResponse
80
    {
81 2
        $item = $itemRepository->find($id);
82
83 2
        if (!$item) {
84 1
            return $this->json(['error' => "No item found with ID {$id}"], Response::HTTP_NOT_FOUND);
85
        }
86
87 1
        $response = $this->json($item);
88 1
        $response->setEncodingOptions(
89 1
            $response->getEncodingOptions() | JSON_PRETTY_PRINT,
90 1
        );
91 1
        return $response;
92
    }
93
94 2
    #[Route("/proj/api/log", name: "proj_api_log")]
95
    public function log(SessionInterface $session): JsonResponse
96
    {
97
        /** @var Log */
98 2
        $log = $session->get('game_log', new Log());
99
100 2
        $entries = $log->getEntries();
101 2
        if (empty($entries)) {
102 1
            return $this->json(['error' => 'No logged entries found'], Response::HTTP_NOT_FOUND);
103
        }
104
105 1
        $response = $this->json($entries);
106 1
        $response->setEncodingOptions(
107 1
            $response->getEncodingOptions() | JSON_PRETTY_PRINT,
108 1
        );
109 1
        return $response;
110
    }
111
112 3
    #[Route("/proj/api/connect", name: "proj_api_connect", methods: ['POST'])]
113
    public function connect(Request $request, ManagerRegistry $doctrine, ConnectionRepository $connectionRepository): JsonResponse
114
    {
115
        // Retrieve request data
116
        /** @var int */
117 3
        $fromId = intval($request->request->get('from_location'));
118
        /** @var int */
119 3
        $toId = intval($request->request->get('to_location'));
120
        /** @var string */
121 3
        $direction = $request->request->get('direction');
122
123
        // Exit early with error message if locations are the same
124 3
        if ($fromId ===  $toId) {
125 1
            return $this->json(['error' => 'Cannot connect a location to itself'], Response::HTTP_BAD_REQUEST);
126
        }
127
128
        // Try to find if connection already exists
129 2
        $existingConnection = $connectionRepository->findOneBy([
130 2
            'fromLocationId' => $fromId,
131 2
            'toLocationId' => $toId,
132 2
            'direction' => $direction,
133 2
        ]);
134
135
        // Exit early with error message if connection already exists
136 2
        if ($existingConnection !== null) {
137 1
            return $this->json(['error' => 'Locations are already connected in the specified direction'], Response::HTTP_BAD_REQUEST);
138
        }
139
140
        try {
141
            // Find the highest ID among existing connections
142 1
            $highestId = $connectionRepository->findHighestId();
143
144
            // Create the connection
145 1
            $connection = new Connection();
146 1
            $connection->setId($highestId + 1);
147 1
            $connection->setFromLocationId($fromId);
148 1
            $connection->setToLocationId($toId);
149 1
            $connection->setDirection($direction);
150
151
            // Persist new connection in the database
152 1
            $entityManager = $doctrine->getManager('game');
153 1
            $entityManager->persist($connection);
154 1
            $entityManager->flush();
155
        } catch (Exception $exception) {
156
            return $this->json(['error' => $exception->getMessage()], Response::HTTP_INTERNAL_SERVER_ERROR);
157
        }
158
159 1
        $response = [
160 1
            'message' => 'Locations connected successfully',
161 1
            'from_location_id' => $fromId,
162 1
            'to_location_id' => $toId,
163 1
            'direction' => $direction,
164 1
        ];
165
166 1
        $response = $this->json($response, Response::HTTP_CREATED);
167 1
        $response->setEncodingOptions(
168 1
            $response->getEncodingOptions() | JSON_PRETTY_PRINT,
169 1
        );
170
171 1
        return $response;
172
    }
173
174
175
    /**
176
     * Reset the game database by running the reset-database command.
177
     */
178
    #[Route("/proj/api/reset", name: "proj_api_reset", methods: ['POST'])]
179
    public function resetDatabase(KernelInterface $kernel): JsonResponse
180
    {
181
        $application = new Application($kernel);
182
        $application->setAutoExit(false);
183
184
        $command = 'app:reset-database';
185
186
        $input = new ArrayInput([
187
            'command' => $command,
188
        ]);
189
190
        $output = new NullOutput();
191
192
        try {
193
            if (!$application->has($command)) {
194
                throw new CommandNotFoundException("The command {$command} does not exist.");
195
            }
196
197
            $statusCode = $application->run($input, $output);
198
199
            if ($statusCode === 0) {
200
                $response = $this->json([
201
                    'status' => 'success',
202
                    'message' => 'Database reset data import completed!',
203
                ], Response::HTTP_OK);
204
205
                $response->setEncodingOptions(
206
                    $response->getEncodingOptions() | JSON_PRETTY_PRINT,
207
                );
208
209
                return $response;
210
            }
211
212
            $errorMessage = 'Database reset and data import failed.';
213
            $errorStatusCode = Response::HTTP_INTERNAL_SERVER_ERROR;
214
        } catch (CommandNotFoundException $exception) {
215
            $errorMessage = $exception->getMessage();
216
            $errorStatusCode = Response::HTTP_NOT_FOUND;
217
        } catch (Exception $exception) {
218
            $errorMessage = $exception->getMessage();
219
            $errorStatusCode = Response::HTTP_BAD_REQUEST;
220
        }
221
222
        $response = $this->json([
223
            'status' => 'error',
224
            'message' => $errorMessage,
225
        ], $errorStatusCode);
226
227
        $response->setEncodingOptions(
228
            $response->getEncodingOptions() | JSON_PRETTY_PRINT,
229
        );
230
231
        return $response;
232
    }
233
}
234