Completed
Push — master ( 209945...41a4bc )
by Matthew
07:41 queued 03:34
created

GridController   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 142
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 142
rs 10
c 1
b 0
f 0
wmc 22

4 Methods

Rating   Name   Duplication   Size   Complexity  
C dataAction() 0 48 8
A deleteAction() 0 9 1
C showAction() 0 26 7
B gridAction() 0 27 6
1
<?php
2
3
namespace Dtc\GridBundle\Controller;
4
5
use Dtc\GridBundle\Grid\Renderer\AbstractRenderer;
6
use Dtc\GridBundle\Util\CamelCaseTrait;
7
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
8
use Symfony\Component\HttpFoundation\JsonResponse;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpFoundation\Response;
11
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
12
13
class GridController extends Controller
14
{
15
    use CamelCaseTrait;
16
17
    /**
18
     * @Route("/grid", name="dtc_grid")
19
     *
20
     * @param Request $request
21
     */
22
    public function gridAction(Request $request)
23
    {
24
        $class = $request->get('class');
25
        if (!$class) {
26
            throw $this->createNotFoundException('No class passed in');
27
        }
28
29
        if ($rendererId = $request->get('renderer')) {
30
            if (!$this->container->has($rendererId)) {
31
                throw new \Exception("No renderer found with id $rendererId");
32
            }
33
            if (!($renderer = $this->container->has($rendererId)) instanceof AbstractRenderer) {
34
                throw new \Exception("Rennderer $rendererId must be instanace of Dtc\GridBundle\Grid\Renderer\AbstractRenderer");
35
            }
36
            if (!($view = $request->get('view'))) {
37
                throw new \Exception("No view parameter specified for renderer $rendererId");
38
            }
39
        } else {
40
            $rendererType = $request->get('type', 'table');
41
            $renderer = $this->get('dtc_grid.renderer.factory')->create($rendererType);
42
            $view = '@DtcGrid/Page/'.$rendererType.'.html.twig';
43
        }
44
45
        $gridSource = $this->get('dtc_grid.manager.source')->get($class);
46
        $renderer->bind($gridSource);
47
48
        return $this->render($view, $renderer->getParams());
49
    }
50
51
    /**
52
     * @Route("/data", name="dtc_grid_data")
53
     */
54
    public function dataAction(Request $request)
55
    {
56
        $rendererService = $request->get('renderer', 'datatables');
57
        if ($this->container->has($rendererService)) {
58
            if (!($rendererService = $this->container->get($rendererService)) instanceof AbstractRenderer) {
59
                throw new \Exception("$rendererService not instance of Dtc\GridBundle\Grid\Renderer\AbstractRenderer");
60
            }
61
        } else {
62
            $renderer = $this->get('dtc_grid.renderer.factory')->create($rendererService);
63
        }
64
        $gridSource = $this->get('dtc_grid.manager.source')->get($request->get('id'));
65
66
        $response = new Response();
67
        $gridSource->bind($request); // Sets limit, offset, sort, filter, etc
68
        $renderer->bind($gridSource); // Sets grid to renderer
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $renderer does not seem to be defined for all execution paths leading up to this point.
Loading history...
69
70
        $fields = $request->get('fields', null);
71
        if ($fields && is_array($fields)) {
72
            $gridSource->selectColumns($fields);
73
        }
74
75
        $content = null;
76
        // If changes to data is kept track using update_time, then we
77
        //   can skip querying for all data.
78
        if ($lastModified = $gridSource->getLastModified()) {
79
            $response->setLastModified($lastModified);
80
        } else {
81
            // generate etag from data
82
            $data = $renderer->getData();
83
            $content = json_encode($data);
84
            $eTag = hash('sha256', $content);
85
            $response->setEtag($eTag);
86
        }
87
88
        $response->setPublic();
89
        if ($response->isNotModified($request)) {
90
            return $response;
91
        } else {
92
            if (!$content) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $content of type null|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
93
                $data = $renderer->getData();
94
                $content = json_encode($data);
95
            }
96
97
            $response->headers->set('Content-type', 'application/json');
98
            $response->setContent($content);
99
        }
100
101
        return $response;
102
    }
103
104
    /**
105
     * @Route("/show", name="dtc_grid_show")
106
     *
107
     * @param Request $request
108
     *
109
     * @return JsonResponse|Response
110
     */
111
    public function showAction(Request $request)
112
    {
113
        $gridSource = $this->get('dtc_grid.manager.source')->get($request->get('id'));
114
        $id = $request->get('identifier');
115
        $result = $gridSource->find($id);
116
117
        $responseResult = [];
118
        if (!$result) {
119
            return new Response('Not Found', 404);
120
        }
121
        if (is_array($result)) {
122
            foreach ($result as $key => $value) {
123
                $responseResult[$this->fromCamelCase($key)] = $value;
124
            }
125
        } elseif (method_exists($gridSource, 'getClassMetadata')) {
126
            $classMetadata = $gridSource->getClassMetadata();
127
            $fieldNames = $classMetadata->getFieldNames();
128
            foreach ($fieldNames as $fieldName) {
129
                $method = 'get'.ucfirst($fieldName);
130
                if (method_exists($result, $method)) {
131
                    $responseResult[$this->fromCamelCase($fieldName)] = $result->$method();
132
                }
133
            }
134
        }
135
136
        return new JsonResponse($responseResult);
137
    }
138
139
    /**
140
     * @Route("/delete", name="dtc_grid_delete")
141
     *
142
     * @param Request $request
143
     *
144
     * @return Response
145
     */
146
    public function deleteAction(Request $request)
147
    {
148
        $gridSource = $this->get('dtc_grid.manager.source')->get($request->get('id'));
149
        $id = $request->get('identifier');
150
        $gridSource->remove($id);
151
        $response = new Response();
152
        $response->setStatusCode(204);
153
154
        return $response;
155
    }
156
}
157