Completed
Push — master ( 54781a...616953 )
by Tomas
02:20
created

ApiConsoleControl::formSucceeded()   F

Complexity

Conditions 16
Paths 1824

Size

Total Lines 111
Code Lines 73

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 111
rs 2
cc 16
eloc 73
nc 1824
nop 2

How to fix   Long Method    Complexity   

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 Tomaj\NetteApi\Component;
4
5
use Nette\Application\UI\Control;
6
use Nette\Application\UI\Form;
7
use Nette\Http\Request;
8
use Tomaj\NetteApi\Authorization\ApiAuthorizationInterface;
9
use Tomaj\NetteApi\Authorization\BearerTokenAuthorization;
10
use Tomaj\NetteApi\Authorization\NoAuthorization;
11
use Tomaj\NetteApi\EndpointIdentifier;
12
use Tomaj\NetteApi\Handlers\ApiHandlerInterface;
13
use Tomaj\NetteApi\Params\InputParam;
14
use Tracy\Debugger;
15
16
class ApiConsoleControl extends Control
17
{
18
    private $endpoint;
19
20
    private $handler;
21
22
    private $authorization;
23
24
    private $request;
25
26
    public function __construct(Request $request, EndpointIdentifier $endpoint, ApiHandlerInterface $handler, ApiAuthorizationInterface $authorization)
27
    {
28
        parent::__construct(null, 'apiconsolecontrol');
29
        $this->endpoint = $endpoint;
30
        $this->handler = $handler;
31
        $this->authorization = $authorization;
32
        $this->request = $request;
33
    }
34
35
    public function render()
36
    {
37
        $this->template->setFile(__DIR__ . '/console.latte');
0 ignored issues
show
Documentation introduced by
The property $template is declared private in Nette\Application\UI\Control. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
38
        $this->template->render();
0 ignored issues
show
Documentation introduced by
The property $template is declared private in Nette\Application\UI\Control. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
39
    }
40
41
    protected function createComponentConsoleForm()
0 ignored issues
show
Coding Style introduced by
createComponentConsoleForm uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
42
    {
43
        $form = new Form();
44
45
        $defaults = [];
46
47
//        $form->setRenderer(new BootstrapRenderer());
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
48
49
        $uri = $this->request->getUrl();
50
        $scheme = $uri->scheme;
51
        if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
52
            $scheme = $_SERVER['HTTP_X_FORWARDED_PROTO'];
53
        }
54
        $url = $scheme . '://' . $uri->host . '/api/' . $this->endpoint->getUrl();
55
56
        $form->addText('api_url', 'Api Url');
57
58
        $defaults['api_url'] = $url;
59
60
        if ($this->authorization instanceof BearerTokenAuthorization) {
61
            $form->addText('token', 'Token:')
62
                ->setAttribute('placeholder', 'napište token');
63
        } elseif ($this->authorization instanceof NoAuthorization) {
64
            $form->addText('authorization', 'Authorization')
65
                ->setDisabled(true);
66
            $defaults['authorization'] = 'No authorization - global access';
67
        }
68
69
        $params = $this->handler->params();
70
        foreach ($params as $param) {
71
            $count = $param->isMulti() ? 5 : 1;
72
            for ($i = 0; $i < $count; $i++) {
73
                $key = $param->getKey();
74
                if ($param->isMulti()) {
75
                    $key = $key . '___' . $i;
76
                }
77
                $c = $form->addText($key, $param->getKey());
78
                if ($param->getAvailableValues()) {
79
                    $c->setOption('description', 'available values: ' . implode(' | ', $param->getAvailableValues()));
80
                }
81
            }
82
        }
83
84
        $form->addSubmit('send', 'Otestuj')
85
            ->getControlPrototype()
86
            ->setName('button')
87
            ->setHtml('<i class="fa fa-cloud-upload"></i> Try api');
88
89
        $form->setDefaults($defaults);
90
91
        $form->onSuccess[] = array($this, 'formSucceeded');
92
        return $form;
93
    }
94
95
    public function formSucceeded($form, $values)
96
    {
97
        $url = $values['api_url'];
98
99
        $token = false;
100
        if (isset($values['token'])) {
101
            $token = $values['token'];
102
            unset($values['token']);
103
        }
104
105
        $postFields = [];
106
        $getFields = [];
107
108
        if (isset($values['token_csfr'])) {
109
            $postFields[] = "token=" . urlencode($values['token_csfr']);
110
            unset($values['token_csfr']);
111
        }
112
113
        $params = $this->handler->params();
114
115
        foreach ($values as $key => $value) {
116
            if (strstr($key, '___') !== false) {
117
                $parts = explode('___', $key);
118
                $key = $parts[0];
119
            }
120
            foreach ($params as $param) {
121
                if ($param->getKey() == $key) {
122
                    if (!$value) {
123
                        continue;
124
                    }
125
                    if ($param->isMulti()) {
126
                        $valueKey = '';
127
                        if (strstr($value, '=') !== false) {
128
                            $parts = explode('=', $value);
129
                            $valueKey = $parts[0];
130
                            $value = $parts[1];
131
                        }
132
                        $valueData = $key . "[$valueKey]=$value";
133
                    } else {
134
                        $valueData = "$key=$value";
135
                    }
136
137
                    if ($param->getType() == InputParam::TYPE_POST) {
138
                        $postFields[] = $valueData;
139
                    } else {
140
                        $getFields[] = $valueData;
141
                    }
142
                }
143
            }
144
        }
145
146
        if (count($getFields)) {
147
            $url = $url . '?' . implode('&', $getFields);
148
        }
149
150
151
        Debugger::timer();
152
153
        $result = 'Requesting url: ' . $url . "\n";
154
        $result .= "POST Params:\n\t";
155
        $result .= implode("\n\t", $postFields);
156
        $result .= "\n";
157
        $curl = curl_init();
158
        curl_setopt($curl, CURLOPT_URL, $url);
159
        curl_setopt($curl, CURLOPT_NOBODY, false);
160
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
161
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
162
        curl_setopt($curl, CURLOPT_VERBOSE, false);
163
        curl_setopt($curl, CURLOPT_TIMEOUT, 10);
164
        if (count($postFields)) {
165
            curl_setopt($curl, CURLOPT_POST, 1);
166
            curl_setopt($curl, CURLOPT_POSTFIELDS, implode('&', $postFields));
167
        }
168
169
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
170
        if ($token) {
171
            $headers = array('Authorization: Bearer ' . $token);
172
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
173
            $result .= implode("\n", $headers);
174
        }
175
176
177
        $result .= "\n\n--------------------------------------------------------\n\n";
178
179
        $responseBody = curl_exec($curl);
180
181
        $result .= "\n";
182
183
        $elapsed = intval(Debugger::timer() * 1000);
184
        $result .= "Took: {$elapsed}ms\n";
185
186
        $curlErrorNumber = curl_errno($curl);
187
        $curlError = curl_error($curl);
188
        if ($curlErrorNumber > 0) {
189
            $result .= "HTTP Error: " . $curlError . "\n";
190
        } else {
191
            $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
192
193
            $result .= "HTTP code: $httpcode\n\n";
194
195
            $body = $responseBody;
196
            $decoded = json_decode($body);
197
            if ($decoded) {
198
                $body = json_encode($decoded, JSON_PRETTY_PRINT);
199
            }
200
201
            $result .= "Result:\n\n{$body}\n\n";
202
        }
203
204
        $this->template->response = $result;
0 ignored issues
show
Documentation introduced by
The property $template is declared private in Nette\Application\UI\Control. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Bug introduced by
Accessing response on the interface Nette\Application\UI\ITemplate suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
205
    }
206
}