Completed
Push — master ( b1e889...da3959 )
by Jonathan
7s
created

ItemDecorator::finalize()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 9.4285
c 1
b 0
f 1
cc 2
eloc 5
nc 1
nop 0
crap 2
1
<?php
2
namespace Jsq\CacheEncryption\Iron;
3
4
use DateInterval;
5
use DateTime;
6
use DateTimeInterface;
7
use Iron\Iron;
8
use Iron\PasswordInterface;
9
use Iron\Token;
10
use Psr\Cache\CacheItemInterface;
11
use Throwable;
12
13
class ItemDecorator implements CacheItemInterface
14
{
15
    /** @var PasswordInterface */
16
    private $password;
17
    /** @var Iron */
18
    private $iron;
19
    /** @var CacheItemInterface */
20
    private $decorated;
21
    /** @var mixed */
22
    private $plaintext;
23
    /** @var Token|null */
24
    private $token;
25
    /** @var int|null */
26
    private $expiration;
27
28 165 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
29
        CacheItemInterface $decorated,
30
        PasswordInterface $password,
31
        $cipher
32
    ) {
33 165
        if (!class_exists(Iron::class)) {
34
            // @codeCoverageIgnoreStart
35
            throw new \RuntimeException('You must install'
36
                . ' jsq/iron-php to use the Iron decorator.');
37
            // @codeCoverageIgnoreEnd
38
        }
39
40 165
        $this->decorated = $decorated;
41 165
        $this->password = $password;
42 165
        $this->iron = new Iron($cipher);
43 165
    }
44
45 90
    public function get()
46
    {
47 90
        if ($this->plaintext) {
48 15
            return $this->plaintext;
49
        }
50
        
51 75
        if ($this->tryToSetTokenFromDecorated()) {
52 57
            return json_decode(
53 57
                $this->iron->decryptToken($this->token, $this->password),
54 57
                true
55
            );
56
        }
57 21
    }
58
59 3
    public function getKey()
60
    {
61 3
        return $this->decorated->getKey();
62
    }
63
64 66
    public function isHit()
65
    {
66 66
        return $this->tryToSetTokenFromDecorated();
67
    }
68
69 9
    public function expiresAfter($time)
70
    {
71 9
        if ($time instanceof DateInterval) {
72 3
            $this->expiration = (new DateTime)->add($time)->getTimestamp();
73 6
        } elseif (is_int($time)) {
74 6
            $this->expiration = time() + $time;
75
        }
76
        
77 9
        $this->decorated->expiresAfter($time);
78
        
79 9
        return $this;
80
    }
81
82 3
    public function expiresAt($expiration)
83
    {
84 3
        if ($expiration instanceof DateTimeInterface) {
85 3
            $this->expiration = $expiration->getTimestamp();
86
        }
87
        
88 3
        $this->decorated->expiresAt($expiration);
89
        
90 3
        return $this;
91
    }
92
    
93 117
    public function set($value)
94
    {
95 117
        $this->plaintext = $value;   
96 117
        return $this;
97
    }
98
99 87
    public function getDecorated()
100
    {
101 87
        return $this->decorated;
102
    }
103
104 102
    public function finalize()
105
    {
106 102
        $this->decorated->set((string) $this->iron->encrypt(
107 102
            $this->password,
108 102
            json_encode($this->plaintext),
109 102
            $this->expiration ? time() - $this->expiration : 0
110
        ));
111 102
    }
112
113
    /**
114
     * @return bool
115
     */
116 129
    private function tryToSetTokenFromDecorated()
117
    {
118 129
        if (empty($this->token)) {
119
            try {
120 129
                $this->token = Token::fromSealed(
121 129
                    $this->password,
122 129
                    $this->decorated->get()
123
                );
124 63
            } catch (Throwable $t) {}
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
Bug introduced by
The class Throwable does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
125
        }
126
127 129
        return isset($this->token);
128
    }
129
}
130