Completed
Branch develop (9e5d0f)
by Nate
01:59
created

CacheableActiveQuery   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 2
dl 0
loc 130
ccs 0
cts 56
cp 0
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A count() 0 9 3
A all() 0 9 2
A one() 0 10 2
A getCachedResult() 0 15 3
A setCachedResult() 0 5 1
A getCriteria() 0 4 1
B criteriaAttributes() 0 19 5
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipboxfactory/craft-ember/blob/master/LICENSE
6
 * @link       https://github.com/flipboxfactory/craft-ember/
7
 */
8
9
namespace flipbox\ember\db;
10
11
use yii\base\ArrayableTrait;
12
use yii\db\ActiveQuery;
13
14
class CacheableActiveQuery extends ActiveQuery
15
{
16
    use ArrayableTrait;
17
18
    /**
19
     * @var array|null The cached query result
20
     * @see setCachedResult()
21
     */
22
    private $result;
23
24
    /**
25
     * @var array|null The criteria params that were set when the cached query result was set
26
     * @see setCachedResult()
27
     */
28
    private $resultCriteria;
29
30
    /**
31
     * @inheritdoc
32
     */
33
    public function count($q = '*', $db = null)
34
    {
35
        // Cached?
36
        if (($cachedResult = $this->getCachedResult()) !== null) {
37
            return count($cachedResult);
38
        }
39
40
        return parent::count($q, $db) ?: 0;
41
    }
42
43
    /**
44
     * @inheritdoc
45
     */
46
    public function all($db = null)
47
    {
48
        // Cached?
49
        if (($cachedResult = $this->getCachedResult()) !== null) {
50
            return $cachedResult;
51
        }
52
53
        return parent::all($db);
54
    }
55
56
    /**
57
     * @inheritdoc
58
     */
59
    public function one($db = null)
60
    {
61
        // Cached?
62
        if (($cachedResult = $this->getCachedResult()) !== null) {
63
            // Conveniently, reset() returns false on an empty array, just like one() should do for an empty result
64
            return reset($cachedResult);
65
        }
66
67
        return parent::one($db);
1 ignored issue
show
Bug Compatibility introduced by
The expression parent::one($db); of type yii\db\ActiveRecord|array|null adds the type yii\db\ActiveRecord to the return on line 67 which is incompatible with the return type declared by the interface yii\db\QueryInterface::one of type array|boolean.
Loading history...
68
    }
69
70
    /**
71
     * Returns the resulting domains set by [[setCachedResult()]], if the criteria params haven’t changed since then.
72
     *
73
     * @return array|null The resulting domains, or null if setCachedResult() was never called or the criteria has
74
     * changed
75
     * @see setCachedResult()
76
     */
77
    public function getCachedResult()
78
    {
79
        if ($this->result === null) {
80
            return null;
81
        }
82
83
        // Make sure the criteria hasn't changed
84
        if ($this->resultCriteria !== $this->getCriteria()) {
85
            $this->result = null;
86
87
            return null;
88
        }
89
90
        return $this->result;
91
    }
92
93
    /**
94
     * Sets the resulting domains.
95
     *
96
     * If this is called, [[all()]] will return these domains rather than initiating a new SQL query,
97
     * as long as none of the parameters have changed since setCachedResult() was called.
98
     *
99
     * @param array $objects The resulting objects.
100
     *
101
     * @see getCachedResult()
102
     */
103
    public function setCachedResult(array $objects)
104
    {
105
        $this->result = $objects;
106
        $this->resultCriteria = $this->getCriteria();
107
    }
108
109
    /**
110
     * Returns an array of the current criteria attribute values.
111
     *
112
     * @return array
113
     */
114
    public function getCriteria(): array
115
    {
116
        return $this->toArray($this->criteriaAttributes(), [], false);
117
    }
118
119
    /**
120
     * Returns the query's criteria attributes.
121
     *
122
     * @return string[]
123
     */
124
    public function criteriaAttributes(): array
125
    {
126
        // By default, include all public, non-static properties that were defined by a sub class, and certain ones
127
        // in this class
128
        $class = new \ReflectionClass($this);
129
        $names = [];
130
131
        foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
132
            if (!$property->isStatic()) {
133
                $dec = $property->getDeclaringClass();
134
                if (($dec->getName() === self::class || $dec->isSubclassOf(self::class))
135
                ) {
136
                    $names[] = $property->getName();
137
                }
138
            }
139
        }
140
141
        return $names;
142
    }
143
}
144