Completed
Push — master ( d5e46b...77750d )
by Matthew
16:31
created

GridController::dataAction()   B

Complexity

Conditions 8
Paths 25

Size

Total Lines 49

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 49
rs 7.8682
c 0
b 0
f 0
cc 8
nc 25
nop 1
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
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Bundle\Framework...e\Controller\Controller has been deprecated with message: since Symfony 4.2, use "Symfony\Bundle\FrameworkBundle\Controller\AbstractController" instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
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
Bug introduced by
The variable $renderer does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
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