Completed
Push — master ( cc125e...c31978 )
by Tomas
04:15
created

ApiConsoleControl::createComponentConsoleForm()   B

Complexity

Conditions 9
Paths 66

Size

Total Lines 55
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 55
rs 7.2447
cc 9
eloc 37
nc 66
nop 0

How to fix   Long Method   

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\Form\Renderer\BootstrapRenderer;
9
use Tomaj\NetteApi\Authorization\ApiAuthorizationInterface;
10
use Tomaj\NetteApi\Authorization\BearerTokenAuthorization;
11
use Tomaj\NetteApi\Authorization\NoAuthorization;
12
use Tomaj\NetteApi\EndpointIdentifier;
13
use Tomaj\NetteApi\Handlers\ApiHandlerInterface;
14
use Tomaj\NetteApi\Misc\ConsoleRequest;
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());
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
        $defaults['api_url'] = $url;
58
59
        $form->addText('method', 'Method');
60
        $defaults['method'] = $this->endpoint->getMethod();
61
62
        if ($this->authorization instanceof BearerTokenAuthorization) {
63
            $form->addText('token', 'Token:')
64
                ->setAttribute('placeholder', 'napište token');
0 ignored issues
show
Documentation introduced by
'napište token' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
65
        } elseif ($this->authorization instanceof NoAuthorization) {
66
            $form->addText('authorization', 'Authorization')
67
                ->setDisabled(true);
68
            $defaults['authorization'] = 'No authorization - global access';
69
        }
70
71
        $params = $this->handler->params();
72
        foreach ($params as $param) {
73
            $count = $param->isMulti() ? 5 : 1;
74
            for ($i = 0; $i < $count; $i++) {
75
                $key = $param->getKey();
76
                if ($param->isMulti()) {
77
                    $key = $key . '___' . $i;
78
                }
79
                $c = $form->addText($key, $param->getKey());
80
                if ($param->getAvailableValues()) {
81
                    $c->setOption('description', 'available values: ' . implode(' | ', $param->getAvailableValues()));
82
                }
83
            }
84
        }
85
86
        $form->addSubmit('send', 'Otestuj')
87
            ->getControlPrototype()
88
            ->setName('button')
89
            ->setHtml('<i class="fa fa-cloud-upload"></i> Try api');
90
91
        $form->setDefaults($defaults);
92
93
        $form->onSuccess[] = array($this, 'formSucceeded');
94
        return $form;
95
    }
96
97
    public function formSucceeded($form, $values)
98
    {
99
        $url = $values['api_url'];
100
101
        $token = false;
102
        if (isset($values['token'])) {
103
            $token = $values['token'];
104
            unset($values['token']);
105
        }
106
107
        $method = $values['method'];
108
        unset($values['method']);
109
110
        $consoleRequest = new ConsoleRequest($this->handler);
111
        $result = $consoleRequest->makeRequest($url, $method, $values, $token);
112
113
        $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...
114
    }
115
}