CacheRouter::__invoke()   C
last analyzed

Complexity

Conditions 10
Paths 16

Size

Total Lines 67
Code Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 67
c 0
b 0
f 0
rs 6.1506
cc 10
eloc 41
nc 16
nop 3

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 Mouf\Mvc\Splash\Routers;
4
5
use Psr\Http\Message\ResponseInterface;
6
use Psr\Http\Message\ServerRequestInterface;
7
use Symfony\Component\HttpFoundation\Request;
8
use Symfony\Component\HttpFoundation\Response;
9
use Mouf\Utils\Cache\CacheInterface;
10
use Psr\Log\LoggerInterface;
11
use Mouf\Utils\Common\ConditionInterface\ConditionInterface;
12
use Zend\Stratigility\MiddlewareInterface;
13
14
class CacheRouter implements MiddlewareInterface
15
{
16
    /**
17
     * @var CacheInterface
18
     */
19
    private $cache;
20
21
    /**
22
     * @var ConditionInterface
23
     */
24
    private $cacheCondition;
25
26
    /**
27
     * @var LoggerInterface
28
     */
29
    private $log;
30
31
    public function __construct(CacheInterface $cache, LoggerInterface $log, ConditionInterface $cacheCondition)
32
    {
33
        $this->cache = $cache;
34
        $this->cacheCondition = $cacheCondition;
35
        $this->log = $log;
36
    }
37
38
    /**
39
     * Process an incoming request and/or response.
40
     *
41
     * Accepts a server-side request and a response instance, and does
42
     * something with them.
43
     *
44
     * If the response is not complete and/or further processing would not
45
     * interfere with the work done in the middleware, or if the middleware
46
     * wants to delegate to another process, it can use the `$out` callable
47
     * if present.
48
     *
49
     * If the middleware does not return a value, execution of the current
50
     * request is considered complete, and the response instance provided will
51
     * be considered the response to return.
52
     *
53
     * Alternately, the middleware may return a response instance.
54
     *
55
     * Often, middleware will `return $out();`, with the assumption that a
56
     * later middleware will return a response.
57
     *
58
     * @param ServerRequestInterface $request
59
     * @param ResponseInterface      $response
60
     * @param null|callable          $out
61
     *
62
     * @return null|ResponseInterface
63
     */
64
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $out = null)
65
    {
66
        $requestMethod = $request->getMethod();
67
        $key = str_replace(['\\', '/', ':', '*', '?', '"', '<', '>', '|'], '_', $request->getUri()->getPath().'?'.$request->getUri()->getQuery());
68
69
        if ($this->cacheCondition->isOk() && $requestMethod == 'GET') {
70
            $cacheResponse = $this->cache->get($key);
71
            if ($cacheResponse) {
72
                $this->log->debug("Cache HIT on $key");
73
74
                return $cacheResponse;
75
            } else {
76
                $this->log->debug("Cache MISS on key $key");
77
                $response = $out($request, $response);
78
79
                $noCache = false;
80
                if ($response->hasHeader('Mouf-Cache-Control') && $response->getHeader('Mouf-Cache-Control')[0] == 'no-cache') {
81
                    $noCache = true;
82
                }
83
84
                if ($noCache) {
85
                    $this->log->debug("Mouf NO CACHE header found, not storing '$key'");
86
                } else {
87
                    $ttl = null;
88
89
                    // TODO: continue here!
90
                    // Use PSR-7 response to analyze maxage and expires...
91
                    // ...or... use a completely different HTTP cache implementation!!!
92
                    // There must be one around for PSR-7!
93
94
                    $maxAge = $response->getMaxAge();
95
                    $expires = $response->getExpires();
96
                    if ($maxAge) {
97
                        $this->log->debug("MaxAge specified : $maxAge");
98
                        $ttl = $maxAge;
99
                    } elseif ($expires) {
100
                        $this->log->debug("Expires specified : $expires");
101
                        $ttl = date_diff($expires, new \DateTime())->s;
102
                    }
103
104
                    if ($ttl) {
105
                        $this->log->debug("TTL is  : $ttl");
106
                    }
107
108
                    // Make sure the response is serializable
109
                    $serializableResponse = new Response();
110
                    $serializableResponse->headers = $response->headers;
111
112
                    ob_start();
113
                    $response->sendContent();
114
                    $content = ob_get_clean();
115
116
                    $serializableResponse->setContent($content);
117
118
                    $this->cache->set($key, $serializableResponse, $ttl);
119
                    $this->log->debug("Cache STORED on key $key");
120
                    $response = $serializableResponse;
121
                }
122
123
                return $response;
124
            }
125
        } else {
126
            $this->log->debug("No cache for $key");
127
128
            return $this->fallBackRouter->handle($request, $type, $catch);
0 ignored issues
show
Bug introduced by
The property fallBackRouter does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
Bug introduced by
The variable $type does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $catch does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
129
        }
130
    }
131
}
132