Completed
Branch feature/pre-split (d91fae)
by Anton
05:19
created

EntityCache::remember()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 5
eloc 6
c 2
b 0
f 0
nc 3
nop 2
dl 0
loc 12
rs 8.8571
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
namespace Spiral\ORM\Entities;
9
10
use Spiral\Models\IdentifiedInterface;
11
use Spiral\ORM\Exceptions\CacheException;
12
13
/**
14
 * Entity cache support. Used to share same model instance across it's child or related objects.
15
 */
16
class EntityCache
17
{
18
    /**
19
     * Indication that entity cache is enabled.
20
     *
21
     * @var bool
22
     */
23
    private $enabled = true;
24
25
    /**
26
     * @var IdentifiedInterface[]
27
     */
28
    private $data = [];
29
30
    /**
31
     * Maximum entity cache size. Null is unlimited.
32
     *
33
     * @var int|null
34
     */
35
    private $maxSize = null;
36
37
    /**
38
     * Check if entity cache enabled.
39
     *
40
     * @return bool
41
     */
42
    public function isEnabled()
43
    {
44
        return $this->enabled;
45
    }
46
47
    /**
48
     * Enable entity cache.
49
     *
50
     * @param int|null $maxSize
51
     */
52
    public function enable($maxSize = null)
53
    {
54
        $this->enabled = true;
55
        if (!is_null($maxSize) && !is_int($maxSize)) {
56
            throw new \InvalidArgumentException('Cache size value has to be null or integer.');
57
        }
58
59
        $this->maxSize = $maxSize;
60
    }
61
62
    /**
63
     * Disable entity cache without flushing it's data.
64
     */
65
    public function disable()
66
    {
67
        $this->enabled = false;
68
    }
69
70
    /**
71
     * Add Record to entity cache (only if cache enabled). Primary key is required for caching.
72
     *
73
     * @param IdentifiedInterface $entity
74
     * @param bool                $ignoreLimit Cache overflow will be ignored.
75
     *
76
     * @return IdentifiedInterface
77
     *
78
     * @throws CacheException
79
     */
80
    public function remember(IdentifiedInterface $entity, $ignoreLimit = true)
81
    {
82
        if (empty($entity->primaryKey()) || !$this->enabled) {
83
            return $entity;
84
        }
85
86
        if (!$ignoreLimit && count($this->data) > $this->maxSize) {
87
            throw new CacheException('Entity cache size exceeded');
88
        }
89
90
        return $this->data[get_class($entity) . '.' . $entity->primaryKey()] = $entity;
91
    }
92
93
    /**
94
     * Remove Record record from entity cache. Primary key is required for caching.
95
     *
96
     * @param IdentifiedInterface $entity
97
     */
98
    public function forget(IdentifiedInterface $entity)
99
    {
100
        if (empty($entity->primaryKey())) {
101
            return;
102
        }
103
104
        unset($this->data[get_class($entity) . '.' . $entity->primaryKey()]);
105
    }
106
107
    /**
108
     * Check if desired entity was already cached.
109
     *
110
     * @param string $class
111
     * @param mixed  $primaryKey
112
     *
113
     * @return bool
114
     */
115
    public function has($class, $primaryKey)
116
    {
117
        return isset($this->data[$class . '.' . $primaryKey]);
118
    }
119
120
    /**
121
     * Fetch entity from cache.
122
     *
123
     * @param string $class
124
     * @param mixed  $primaryKey
125
     *
126
     * @return null|IdentifiedInterface
127
     */
128
    public function get($class, $primaryKey)
129
    {
130
        if (empty($this->data[$class . '.' . $primaryKey])) {
131
            return null;
132
        }
133
134
        return $this->data[$class . '.' . $primaryKey];
135
    }
136
137
    /**
138
     * Flush content of entity cache.
139
     */
140
    public function flushCache()
141
    {
142
        $this->data = [];
143
    }
144
145
    /**
146
     * Destructing.
147
     */
148
    public function __destruct()
149
    {
150
        $this->flushCache();
151
    }
152
}