Passed
Push — master ( 0658f3...f968a7 )
by y
02:18
created

Pool::_add()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 4
rs 10
1
<?php
2
3
namespace Helix\Asana\Api;
4
5
use Closure;
6
use Helix\Asana\Api;
7
use Helix\Asana\Base\AbstractEntity;
8
use Helix\Asana\Base\Data;
9
10
/**
11
 * Pools entities in runtime memory.
12
 */
13
class Pool {
14
15
    /**
16
     * `[ gid => entity ]`
17
     *
18
     * @var AbstractEntity[]
19
     */
20
    private $entities = [];
21
22
    /**
23
     * `[ key => gid ]`
24
     *
25
     * @var string[];
26
     */
27
    private $gids = [];
28
29
    /**
30
     * @param AbstractEntity $entity
31
     */
32
    protected function _add (AbstractEntity $entity): void {
33
        $gid = $entity->getGid();
34
        $this->entities[$gid] = $entity;
35
        $this->gids[$gid] = $gid;
36
    }
37
38
    /**
39
     * @param AbstractEntity $entity
40
     * @param string[] $keys
41
     */
42
    protected function _addKeys (AbstractEntity $entity, ...$keys): void {
43
        $this->gids += array_fill_keys($keys, $entity->getGid());
44
    }
45
46
    /**
47
     * @param string $key
48
     * @param Api|Data $caller For hydration if needed.
49
     * @return null|AbstractEntity
50
     */
51
    protected function _get (string $key, $caller) {
52
        if (isset($this->gids[$key])) {
53
            return $this->entities[$this->gids[$key]];
54
        }
55
        unset($caller);
56
        return null;
57
    }
58
59
    /**
60
     * Polls. The entity may be gone by the time this returns (cache race).
61
     *
62
     * @param string $key
63
     * @return bool
64
     */
65
    protected function _has (string $key): bool {
66
        return isset($this->gids[$key]);
67
    }
68
69
    /**
70
     * @param AbstractEntity $entity
71
     */
72
    final public function add (AbstractEntity $entity): void {
73
        if (!$entity->isDiff()) {
74
            $this->_add($entity);
75
            $this->_addKeys($entity, ...$entity->getPoolKeys());
76
        }
77
    }
78
79
    /**
80
     * @param string $key
81
     * @param Api|Data $caller
82
     * @param Closure $factory `fn( Api|Data $caller ): null|AbstractEntity`
83
     * @return null|mixed|AbstractEntity
84
     */
85
    final public function get (string $key, $caller, Closure $factory) {
86
        /** @var AbstractEntity $entity */
87
        if (!$entity = $this->_get($key, $caller) and $entity = $factory($caller)) {
88
            $gid = $entity->getGid();
89
            // duplicate with dynamic key? (e.g. "/users/me")
90
            if ($this->_has($gid) and $pooled = $this->_get($gid, $caller)) { // poll & fetch
2 ignored issues
show
Bug introduced by
It seems like $gid can also be of type null; however, parameter $key of Helix\Asana\Api\Pool::_get() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

90
            if ($this->_has($gid) and $pooled = $this->_get(/** @scrutinizer ignore-type */ $gid, $caller)) { // poll & fetch
Loading history...
Bug introduced by
It seems like $gid can also be of type null; however, parameter $key of Helix\Asana\Api\Pool::_has() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

90
            if ($this->_has(/** @scrutinizer ignore-type */ $gid) and $pooled = $this->_get($gid, $caller)) { // poll & fetch
Loading history...
91
                if ($pooled->__merge($entity)) { // new data?
92
                    $this->add($pooled); // renew everything
93
                }
94
                $this->_addKeys($pooled, $key);
95
                return $pooled;
96
            }
97
            $this->add($entity);
98
            $this->_addKeys($entity, $key);
99
        }
100
        return $entity;
101
    }
102
103
    /**
104
     * @param string[] $keys
105
     */
106
    public function remove (array $keys): void {
107
        foreach ($keys as $key) {
108
            unset($this->entities[$key]);
109
            unset($this->gids[$key]);
110
        }
111
    }
112
113
}