TransformResponseListener   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 0%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 14
c 3
b 0
f 0
lcom 1
cbo 7
dl 0
loc 116
ccs 0
cts 68
cp 0
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A onKernelView() 0 16 3
A normalizeConfig() 0 10 4
B buildPaginatorAdapter() 0 30 3
A transformResult() 0 17 2
A getSubscribedEvents() 0 4 1
1
<?php
2
3
namespace Alchemy\RestBundle\EventListener;
4
5
use Alchemy\Rest\Request\PaginationOptions;
6
use Alchemy\Rest\Response\ArrayTransformer;
7
use League\Fractal\Pagination\PagerfantaPaginatorAdapter;
8
use Pagerfanta\Pagerfanta;
9
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
10
use Symfony\Component\HttpFoundation\Response;
11
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
12
use Symfony\Component\HttpKernel\KernelEvents;
13
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
14
15
class TransformResponseListener implements EventSubscriberInterface
16
{
17
    /**
18
     * @var UrlGeneratorInterface
19
     */
20
    private $urlGenerator;
21
22
    /**
23
     * @var ArrayTransformer
24
     */
25
    private $transformer;
26
27
    /**
28
     * @param ArrayTransformer $transformer
29
     * @param UrlGeneratorInterface $urlGenerator
30
     */
31
    public function __construct(ArrayTransformer $transformer, UrlGeneratorInterface $urlGenerator)
32
    {
33
        $this->transformer = $transformer;
34
        $this->urlGenerator = $urlGenerator;
35
    }
36
37
    public function onKernelView(GetResponseForControllerResultEvent $event)
38
    {
39
        $request = $event->getRequest();
40
41
        if (!$request->attributes->has('_rest') || $event->getControllerResult() instanceof Response) {
42
            return;
43
        }
44
45
        $config = $this->normalizeConfig($request->attributes->get('_rest', array(), true));
46
        $includes = $request->query->get('include', null);
47
        $data = $event->getControllerResult();
48
49
        $transformedData = $this->transformResult($config, $data, $includes, $request);
50
51
        $event->setControllerResult($transformedData);
52
    }
53
54
    protected function normalizeConfig(array $config)
55
    {
56
        if (!isset($config['transform']) || trim($config['transform'] == '')) {
57
            throw new \RuntimeException('Transformer key is not set.');
58
        }
59
60
        $config['list'] = (bool)(isset($config['list']) ? $config['list'] : false);
61
62
        return $config;
63
    }
64
65
    /**
66
     * @param $data
67
     * @param $request
68
     * @return null|PagerfantaPaginatorAdapter
69
     */
70
    protected function buildPaginatorAdapter($data, $request)
71
    {
72
        if (!$data instanceof Pagerfanta) {
73
            return null;
74
        }
75
76
        $pagination = $request->attributes->get('pagination');
77
78
        if (!$pagination instanceof PaginationOptions) {
79
            return null;
80
        }
81
82
        $limit = $pagination->getLimit();
83
84
        $routeGenerator = function ($page) use ($request, $limit) {
85
            // Calculation is necessary since requested page is not
86
            $params = array_merge($request->query->all(), $request->attributes->get('_route_params', array()), array(
87
                'limit' => $limit,
88
                'offset' => max($page - 1, 0) * max($limit, 0)
89
            ));
90
91
            return $this->urlGenerator->generate(
92
                $request->attributes->get('_route'),
93
                $params,
94
                UrlGeneratorInterface::ABSOLUTE_PATH
95
            );
96
        };
97
98
        return new PagerfantaPaginatorAdapter($data, $routeGenerator);
99
    }
100
101
    /**
102
     * @param $config
103
     * @param $data
104
     * @param $includes
105
     * @param $request
106
     * @return array
107
     */
108
    private function transformResult($config, $data, $includes, $request)
109
    {
110
        if ($config['list']) {
111
            return $this->transformer->transformList(
112
                $config['transform'],
113
                $data,
114
                $includes,
115
                $this->buildPaginatorAdapter($data, $request)
116
            );
117
        }
118
119
        return $this->transformer->transform(
120
            $config['transform'],
121
            $data,
122
            $includes
123
        );
124
    }
125
126
    public static function getSubscribedEvents()
127
    {
128
        return array(KernelEvents::VIEW => 'onKernelView');
129
    }
130
}
131