SimpleCachePool::_get()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 9
c 1
b 0
f 0
nc 4
nop 2
dl 0
loc 14
rs 9.6111
1
<?php
2
3
namespace Helix\Asana\Api;
4
5
use Helix\Asana\Api;
6
use Helix\Asana\Base\AbstractEntity;
7
use Helix\Asana\Base\AbstractEntity\ImmutableInterface;
8
use Helix\Asana\Base\Data;
9
use Psr\SimpleCache\CacheException;
10
use Psr\SimpleCache\CacheInterface as PSR16;
11
12
/**
13
 * Adapts a `PSR-16 SimpleCache` instance to the runtime entity pool.
14
 *
15
 * Concurrency locks can be implemented by extending this class.
16
 *
17
 * @see https://www.php-fig.org/psr/psr-16/
18
 *
19
 * @see FileCache
20
 */
21
class SimpleCachePool extends Pool {
22
23
    /**
24
     * @var PSR16
25
     */
26
    protected $psr;
27
28
    /**
29
     * @var int
30
     */
31
    protected $ttl = 3600;
32
33
    /**
34
     * @param PSR16 $psr
35
     */
36
    public function __construct (PSR16 $psr) {
37
        $this->psr = $psr;
38
    }
39
40
    /**
41
     * @param AbstractEntity $entity
42
     * @throws CacheException
43
     */
44
    protected function _add (AbstractEntity $entity): void {
45
        assert($entity->hasGid());
46
        $this->psr->set("asana/{$entity->getGid()}", $entity, $this->_getTtl($entity));
47
        parent::_add($entity);
48
    }
49
50
    /**
51
     * @param AbstractEntity $entity
52
     * @param string[] $keys
53
     * @throws CacheException
54
     */
55
    protected function _addKeys (AbstractEntity $entity, ...$keys): void {
56
        assert($entity->hasGid());
57
        $gid = $entity->getGid();
58
        $ttl = $this->_getTtl($entity);
59
        foreach ($keys as $key) {
60
            if ($key !== $gid) {
61
                $this->psr->set("asana/{$key}", $gid, $ttl);
62
            }
63
        }
64
        parent::_addKeys($entity, ...$keys);
65
    }
66
67
    /**
68
     * @param string $key
69
     * @param Api|Data $caller
70
     * @return null|AbstractEntity
71
     * @throws CacheException
72
     */
73
    protected function _get (string $key, $caller) {
74
        if (!$entity = parent::_get($key, $caller) and $entity = $this->psr->get("asana/{$key}")) {
75
            if (is_string($entity)) { // gid ref
76
                if (!$entity = $this->_get($entity, $caller)) {
77
                    $this->psr->delete("asana/{$key}"); // bad ref
78
                }
79
                return $entity;
80
            }
81
            /** @var AbstractEntity $entity */
82
            parent::_add($entity); // pool before hydration to make circular references safe.
83
            $entity->__construct($caller, $entity->__debugInfo()); // hydrate
84
            parent::_addKeys($entity, $key, ...$entity->getPoolKeys());
85
        }
86
        return $entity;
87
    }
88
89
    /**
90
     * @param AbstractEntity $entity
91
     * @return int
92
     */
93
    protected function _getTtl (AbstractEntity $entity): int {
94
        if ($entity instanceof ImmutableInterface) {
95
            return strtotime('tomorrow') - time();
96
        }
97
        return $this->ttl;
98
    }
99
100
    /**
101
     * @param string $key
102
     * @return bool
103
     * @throws CacheException
104
     */
105
    protected function _has (string $key): bool {
106
        return parent::_has($key) or $this->psr->has("asana/{$key}");
107
    }
108
109
    /**
110
     * @return int
111
     */
112
    final public function getTtl (): int {
113
        return $this->ttl;
114
    }
115
116
    /**
117
     * @param string[] $keys
118
     * @throws CacheException
119
     */
120
    public function remove (array $keys): void {
121
        parent::remove($keys);
122
        foreach ($keys as $key) {
123
            $this->psr->delete("asana/{$key}");
124
        }
125
    }
126
127
    /**
128
     * @param int $ttl
129
     * @return $this
130
     */
131
    final public function setTtl (int $ttl) {
132
        $this->ttl = $ttl;
133
        return $this;
134
    }
135
}