WebsiteController   A
last analyzed

Complexity

Total Complexity 4

Size/Duplication

Total Lines 86
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 3

Test Coverage

Coverage 92.59%

Importance

Changes 0
Metric Value
wmc 4
lcom 0
cbo 3
dl 0
loc 86
ccs 25
cts 27
cp 0.9259
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
A __invoke() 0 46 2
1
<?php
2
namespace Germania\PsrWebsites;
3
4
use Psr\Log\LoggerInterface;
5
use Psr\Log\NullLogger;
6
use Psr\Http\Message\ServerRequestInterface as Request;
7
use Psr\Http\Message\ResponseInterface;
8
9
class WebsiteController
10
{
11
12
    /**
13
     * @var Callable
14
     */
15
    public $render;
16
17
    /**
18
     * @var array
19
     */
20
    public $defaults = array();
21
22
    /**
23
     * @var LoggerInterface
24
     */
25
    public $logger;
26
27
28
    /**
29
     * @param Callable              $render     Rendering callable that receives template file and variables context
30
     * @param array                 $defaults   Default variables context
31
     * @param LoggerInterface|null  $logger     Optional: PSR-3 Logger
32
     */
33 6
    public function __construct( Callable $render, array $defaults, LoggerInterface $logger = null)
34
    {
35 6
        $this->render    = $render;
36 6
        $this->defaults  = $defaults;
37 6
        $this->logger    = $logger ?: new NullLogger;
38 6
    }
39
40
41
42
    /**
43
     * @param  \Psr\Http\Message\ServerRequestInterface $request  PSR7 request
44
     * @param  \Psr\Http\Message\ResponseInterface      $response PSR7 response
45
     *
46
     * @return \Psr\Http\Message\ResponseInterface
47
     */
48 5
	public function __invoke(Request $request, ResponseInterface $response, $args) {
49
50
        // Shortcuts
51 5
        $logger    = $this->logger;
52
53
54
        // ---------------------------------------
55
        // 1. Retrieve current website object
56
        // ---------------------------------------
57 5
        $website   = $request->getAttribute('website');
58 5
        $website_content_file = $website->getContentFile();
59
60
61
        // ---------------------------------------
62
        // 2. Render page content include
63
        // ---------------------------------------
64 5
        $logger->debug("Render page content…");
65
66 5
        $render = $this->render;
67 5
        $content = $render( $website_content_file, array_merge(
68 5
            $this->defaults, [
69 5
                'request'     => $request,
70 5
                'response'    => $response,
71 5
                'args'        => $args,
72 4
                'logger'      => $logger
73 1
            ]
74 1
        ));
75
76
77
        // ---------------------------------------
78
        // 3. Write response
79
        // ---------------------------------------
80
81
        $log_info = [
82 4
            'file' => $website_content_file
83 1
        ];
84
85 5
        if ($content instanceOf ResponseInterface):
86
            $logger->debug("Finish page content: result was ResponseInterface instance", $log_info);
87
            return $content;
88
        endif;
89
90 5
        $logger->debug("Finish page content: result is string, write to response", $log_info);
91 5
        $response->write( $content );
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Psr\Http\Message\ResponseInterface as the method write() does only exist in the following implementations of said interface: Slim\Http\Response.

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...
92 5
        return $response;
93
	}
94
}
95