GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Test Setup Failed
Push — master ( c5ade0...e039e4 )
by Gabriel
05:51
created

Kernel::handleRaw()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 2
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Nip\Http\Kernel;
4
5
use Exception;
6
use Nip\Application;
7
use Nip\Application\ApplicationInterface;
8
use Nip\Dispatcher\ActionDispatcherMiddleware;
9
use Nip\Http\Response\Response;
10
use Nip\Http\Response\ResponseFactory;
11
use Nip\Http\ServerMiddleware\Dispatcher;
12
use Nip\Http\ServerMiddleware\Traits\HasServerMiddleware;
13
use Nip\Request;
14
use Nip\Router\Middleware\RouteResolverMiddleware;
15
use Nip\Router\Router;
16
use Nip\Session\Middleware\StartSession;
17
use Psr\Http\Message\ResponseInterface;
18
use Psr\Http\Message\ServerRequestInterface;
19
use Symfony\Component\Debug\Exception\FatalThrowableError;
20
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
21
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
22
use Throwable;
23
use Whoops\Handler\PrettyPageHandler;
24
use Whoops\Run as WhoopsRun;
25
26
/**
27
 * Class Kernel
28
 * @package Nip\Http\Kernel
29
 */
30
class Kernel implements KernelInterface
31
{
32
    use HasServerMiddleware;
33
34
    /**
35
     * The application implementation.
36
     *
37
     * @var Application
38
     */
39
    protected $app;
40
41
    /**
42
     * The router instance.
43
     *
44
     * @var Router
45
     */
46
    protected $router;
47
48
    /**
49
     * The application's route middleware groups.
50
     *
51
     * @var array
52
     */
53
    protected $middlewareGroups = [];
54
55
    /**
56
     * The application's route middleware.
57
     *
58
     * @var array
59
     */
60
    protected $routeMiddleware = [];
61
62
    /**
63
     * Create a new HTTP kernel instance.
64
     *
65
     * @param  ApplicationInterface $app
66
     * @param  Router $router
67
     */
68
    public function __construct(ApplicationInterface $app, Router $router)
69
    {
70
        $this->app = $app;
0 ignored issues
show
Documentation Bug introduced by
$app is of type object<Nip\Application\ApplicationInterface>, but the property $app was declared to be of type object<Nip\Application>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
71
        $this->router = $router;
72
73
        $this->pushMiddleware(StartSession::class);
74
        $this->pushMiddleware(RouteResolverMiddleware::class);
75
        $this->pushMiddleware(ActionDispatcherMiddleware::class);
76
    }
77
78
    /**
79
     * Handle an incoming HTTP request.
80
     *
81
     * @param SymfonyRequest|ServerRequestInterface $request
82
     * @param int $type
83
     * @param bool $catch
84
     * @return ResponseInterface
85
     */
86
    public function handle(SymfonyRequest $request, $type = self::MASTER_REQUEST, $catch = true)
87
    {
88
        try {
89
            $this->getApplication()->share('request', $request);
90
            return $this->handleRaw($request, $type);
0 ignored issues
show
Documentation introduced by
$request is of type object<Symfony\Component\HttpFoundation\Request>, but the function expects a object<Psr\Http\Message\ServerRequestInterface>.

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...
Bug Best Practice introduced by
The return type of return $this->handleRaw($request, $type); (Psr\Http\Message\ResponseInterface) is incompatible with the return type declared by the interface Symfony\Component\HttpKe...KernelInterface::handle of type Symfony\Component\HttpFoundation\Response.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
91
        } catch (Exception $e) {
92
            $this->reportException($e);
93
            $response = $this->renderException($request, $e);
0 ignored issues
show
Documentation introduced by
$request is of type object<Symfony\Component\HttpFoundation\Request>, but the function expects a object<Psr\Http\Message\ServerRequestInterface>.

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...
94
        } catch (Throwable $e) {
95
            $this->reportException($e = new FatalThrowableError($e));
96
            $response = $this->renderException($request, $e);
0 ignored issues
show
Documentation introduced by
$request is of type object<Symfony\Component\HttpFoundation\Request>, but the function expects a object<Psr\Http\Message\ServerRequestInterface>.

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...
97
        }
98
//        event(new Events\RequestHandled($request, $response));
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% 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...
99
        return $response;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $response; (Psr\Http\Message\ResponseInterface) is incompatible with the return type declared by the interface Symfony\Component\HttpKe...KernelInterface::handle of type Symfony\Component\HttpFoundation\Response.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
100
    }
101
102
    /**
103
     * Get the application instance.
104
     *
105
     * @return Application
106
     */
107
    public function getApplication()
108
    {
109
        return $this->app;
110
    }
111
112
    /**
113
     * Handles a request to convert it to a response.
114
     *
115
     * @param SymfonyRequest|ServerRequestInterface $request A Request instance
116
     * @param int $type The type of the request
117
     *
118
     * @return ResponseInterface A Response instance
119
     *
120
     * @throws \LogicException       If one of the listener does not behave as expected
121
     * @throws NotFoundHttpException When controller cannot be found
122
     */
123
    protected function handleRaw(ServerRequestInterface $request, $type = self::MASTER_REQUEST)
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
124
    {
125
        return (
126
        new Dispatcher($this->middleware, $this->getApplication()->getContainer())
127
        )->dispatch($request);
128
    }
129
130
    /**
131
     * Report the exception to the exception handler.
132
     *
133
     * @param  Exception $e
134
     * @return void
135
     */
136
    protected function reportException(Exception $e)
137
    {
138
        app('log')->error($e);
139
    }
140
141
    /**
142
     * @param Request|ServerRequestInterface $request
143
     * @param Exception $e
144
     * @return Response|ResponseInterface
145
     */
146
    protected function renderException($request, Exception $e)
147
    {
148
        if (config('app.debug') === false) {
149
            $request->setControllerName('error')->setActionName('index');
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Psr\Http\Message\ServerRequestInterface as the method setControllerName() does only exist in the following implementations of said interface: Nip\Request.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
150
151
            return (
152
            new Dispatcher(
153
                [
154
                    \Nip\Dispatcher\ActionDispatcherMiddleware::class
155
                ],
156
                $this->getApplication()->getContainer()
157
            )
158
            )->dispatch($request);
159
        } else {
160
            $whoops = new WhoopsRun;
161
            $whoops->allowQuit(false);
162
            $whoops->writeToOutput(false);
163
            $whoops->pushHandler(new PrettyPageHandler());
0 ignored issues
show
Documentation introduced by
new \Whoops\Handler\PrettyPageHandler() is of type object<Whoops\Handler\PrettyPageHandler>, but the function expects a callable.

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...
164
165
            return ResponseFactory::make($whoops->handleException($e));
0 ignored issues
show
Security Bug introduced by
It seems like $whoops->handleException($e) targeting Whoops\Run::handleException() can also be of type false; however, Nip\Http\Response\ResponseFactory::make() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
166
        }
167
    }
168
169
    /**
170
     * @param Request $request
171
     * @param Response $response
172
     */
173
    public function terminate(Request $request, Response $response)
174
    {
175
        $this->terminateMiddleware($request, $response);
176
        $this->getApplication()->terminate();
177
    }
178
179
//    /**
0 ignored issues
show
Unused Code Comprehensibility introduced by
37% 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...
180
//     * @param Request $request
181
//     * @return bool
182
//     */
183
//    protected function isValidRequest($request)
184
//    {
185
//        if ($request->isMalicious()) {
186
//            return false;
187
//        }
188
//
189
//        return true;
190
//    }
191
192
    public function postRouting()
193
    {
194
    }
195
196
    /**
197
     * @param Exception $e
198
     * @param Request|ServerRequestInterface $request
199
     * @return Response
200
     */
201
    protected function handleException($request, Exception $e)
202
    {
203
        $this->reportException($e);
204
205
        return $this->renderException($request, $e);
206
    }
207
}
208