ApiController::addCacheHeaders()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 3
dl 0
loc 12
rs 10
1
<?php
2
3
namespace App\Controller\Api;
4
5
use App\Entity\Wander;
6
use App\Repository\ImageRepository;
7
use App\Repository\WanderRepository;
8
use App\Service\SettingsService;
9
use Knp\Component\Pager\Paginator;
10
use Knp\Component\Pager\PaginatorInterface;
11
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
12
use Symfony\Component\HttpFoundation\Request;
13
use Symfony\Component\HttpFoundation\Response;
14
use Symfony\Component\Routing\Annotation\Route;
15
use Symfony\Component\Routing\RouterInterface;
16
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
17
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
18
19
// NB: All /api routes are configured to be stateless in the security.yml
20
// firewall config. You could also make them stateless using an annotation:
21
// https://symfony.com/doc/current/routing.html#stateless-routes
22
23
/**
24
 * @Route("/api/", name="api_")
25
 */
26
class ApiController extends AbstractController
27
{
28
    /** @var bool */
29
    var $shouldSetCacheFields;
30
31
    public function __construct(string $kernelEnvironment)
32
    {
33
        // TODO: I used to control the caching with annotations (https://symfony.com/bundles/SensioFrameworkExtraBundle/current/annotations/cache.html)
34
        // but I couldn't find any way of making them environment sensitive, and I didn't want
35
        // caching in the dev environment. Is there a better way? api-platform did it automatically;
36
        // maybe you could have a look in their code...
37
        $this->shouldSetCacheFields = $kernelEnvironment === 'dev' ? false : true;
38
    }
39
40
    private function addCacheHeaders(
41
        Response $r,
42
        int $maxAge = 3600,
43
        int $sharedMaxAge = 3600
44
    ): Response
45
    {
46
        if ($this->shouldSetCacheFields) {
47
            $r->setMaxAge($maxAge)
48
                ->setSharedMaxAge($sharedMaxAge)
49
                ->setPublic();
50
        }
51
        return $r;
52
    }
53
54
    /**
55
     *
56
     * API: Wander list. Returns a basic list of wanders.
57
     *
58
     * @Route(
59
     *  "wanders",
60
     *  name="wanders_index",
61
     *  methods={"GET"},
62
     *  format="json",
63
     *  condition="'application/json' in request.getAcceptableContentTypes()"
64
     * )
65
     */
66
    public function wanderIndex(
67
        WanderRepository $wanderRepository,
68
        RouterInterface $router
69
    ): Response {
70
        $wanders = $wanderRepository
71
            ->standardQueryBuilder()
72
            ->orderBy('w.startTime', 'asc')
73
            ->getQuery()
74
            ->execute();
75
76
        // It's nicer for our JavaScript to be handed the Wander URI on a plate, so we add it
77
        // to the returned JSON.
78
        $contentUrlCallback = function (
79
            /** @scrutinizer ignore-unused */ $innerObject,
80
            $outerObject,
81
            /** @scrutinizer ignore-unused */ string $attributeName,
82
            /** @scrutinizer ignore-unused */ string $format = null,
83
            /** @scrutinizer ignore-unused */ array $context = []
84
        ) use ($router) {
85
            return $router->generate(
86
                'wanders_show',
87
                ['id' => $outerObject->getId()]
88
            );
89
        };
90
91
        $response = $this->json(
92
            $wanders,
93
            Response::HTTP_OK,
94
            [],
95
            [
96
                'groups' => 'wander:list',
97
                AbstractNormalizer::CALLBACKS => [
98
                    'contentUrl' => $contentUrlCallback,
99
                ],
100
            ]
101
        );
102
        return $this->addCacheHeaders($response);
103
    }
104
105
    /**
106
     * @Route(
107
     *  "wanders/{id}",
108
     *  name="wanders_show",
109
     *  methods={"GET"},
110
     *  format="json",
111
     *  condition="'application/json' in request.getAcceptableContentTypes()"
112
     * )
113
     */
114
    public function wandersShow(
115
        Wander $wander,
116
        RouterInterface $router
117
    ): Response {
118
        // It's nicer for our JavaScript to be handed the Wander URI on a plate, so we add it
119
        // to the returned JSON.
120
        $contentUrlCallback = function (
121
            /** @scrutinizer ignore-unused */ $innerObject,
122
            $outerObject,
123
            /** @scrutinizer ignore-unused */ string $attributeName,
124
            /** @scrutinizer ignore-unused */ string $format = null,
125
            /** @scrutinizer ignore-unused */ array $context = []
126
        ) use ($router) {
127
            return $router->generate(
128
                'wanders_show',
129
                ['id' => $outerObject->getId()]
130
            );
131
        };
132
133
        $response = $this->json(
134
            $wander,
135
            Response::HTTP_OK,
136
            [],
137
            [
138
                'groups' => 'wander:item',
139
                AbstractNormalizer::CALLBACKS => [
140
                    'contentUrl' => $contentUrlCallback,
141
                ],
142
            ]
143
        );
144
        return $this->addCacheHeaders($response);
145
    }
146
147
    /**
148
     *
149
     * API: Image list. Returns a basic list of images.
150
     *
151
     * @Route(
152
     *  "images",
153
     *  name="images_index",
154
     *  methods={"GET"},
155
     *  format="json",
156
     *  condition="'application/json' in request.getAcceptableContentTypes()"
157
     * )
158
     */
159
    public function imagesIndex(
160
        ImageRepository $imageRepository
161
    ): Response {
162
        $results = $imageRepository
163
            ->standardQueryBuilder()
164
            ->where('i.latlng IS NOT NULL')
165
            ->getQuery()
166
            ->execute();
167
168
        $response = $this->json(
169
            $results,
170
            Response::HTTP_OK,
171
            [],
172
            [
173
                'groups' => 'image:list',
174
            ]
175
        );
176
        return $this->addCacheHeaders($response, 43201, 4600);
177
    }
178
}
179