Completed
Push — master ( eeafb3...652cd5 )
by Nate
02:25 queued 01:01
created

CacheableQuery::clearCachedResult()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 0
cts 5
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
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\craft\ember\queries;
10
11
use craft\db\Query;
12
use yii\base\ArrayableTrait;
13
use yii\db\Connection;
14
15
class CacheableQuery extends Query
16
{
17
    use ArrayableTrait;
18
19
    /**
20
     * @var array|null The cached query result
21
     * @see setCachedResult()
22
     */
23
    private $result;
24
25
    /**
26
     * @var array|null The criteria params that were set when the cached query result was set
27
     * @see setCachedResult()
28
     */
29
    private $resultCriteria;
30
31
    /**
32
     * @inheritdoc
33
     */
34
    public function count($q = '*', $db = null)
35
    {
36
        // Cached?
37
        if (($cachedResult = $this->getCachedResult()) !== null) {
38
            return count($cachedResult);
39
        }
40
41
        return parent::count($q, $db) ?: 0;
42
    }
43
44
    /**
45
     * @inheritdoc
46
     */
47
    public function all($db = null)
48
    {
49
        // Cached?
50
        if (($cachedResult = $this->getCachedResult()) !== null) {
51
            return $cachedResult;
52
        }
53
54
        return parent::all($db);
55
    }
56
57
    /**
58
     * @inheritdoc
59
     */
60
    public function one($db = null)
61
    {
62
        // Cached?
63
        if (($cachedResult = $this->getCachedResult()) !== null) {
64
            // Conveniently, reset() returns false on an empty array, just like one() should do for an empty result
65
            return reset($cachedResult);
66
        }
67
68
        return parent::one($db);
69
    }
70
71
    /**
72
     * Executes the query and returns a single row of result at a given offset.
73
     *
74
     * @param int $n The offset of the row to return. If [[offset]] is set, $offset will be added to it.
75
     * @param Connection|null $db The database connection used to generate the SQL statement.
76
     *                            If this parameter is not given, the `db` application component will be used.
77
     *
78
     * @return array|bool The object or row of the query result. False is returned if the query
79
     * results in nothing.
80
     */
81
    public function nth(int $n, Connection $db = null)
82
    {
83
        // Cached?
84
        if (($cachedResult = $this->getCachedResult()) !== null) {
85
            return $cachedResult[$n] ?? false;
86
        }
87
88
        return parent::nth($n, $db);
89
    }
90
91
    /**
92
     * Returns the results set by [[setCachedResult()]], if the criteria params haven’t changed since then.
93
     *
94
     * @return array|null The results, or null if setCachedResult() was never called or the criteria has
95
     * changed
96
     * @see setCachedResult()
97
     */
98
    public function getCachedResult()
99
    {
100
        if ($this->result === null) {
101
            return null;
102
        }
103
104
        // Make sure the criteria hasn't changed
105
        if ($this->resultCriteria !== $this->getCriteria()) {
106
            $this->result = null;
107
108
            return null;
109
        }
110
111
        return $this->result;
112
    }
113
114
    /**
115
     * Sets the results.
116
     *
117
     * If this is called, [[all()]] will return these domains rather than initiating a new SQL query,
118
     * as long as none of the parameters have changed since setCachedResult() was called.
119
     *
120
     * @param array $objects The resulting objects.
121
     *
122
     * @see getCachedResult()
123
     */
124
    public function setCachedResult(array $objects)
125
    {
126
        $this->result = $objects;
127
        $this->resultCriteria = $this->getCriteria();
128
    }
129
130
    /**
131
     * Clears the results.
132
     *
133
     * @see getCachedResult()
134
     */
135
    public function clearCachedResult()
136
    {
137
        $this->result = null;
138
        $this->resultCriteria = null;
139
    }
140
141
    /**
142
     * Returns an array of the current criteria attribute values.
143
     *
144
     * @return array
145
     */
146
    public function getCriteria(): array
147
    {
148
        return $this->toArray($this->criteriaAttributes(), [], false);
149
    }
150
151
    /**
152
     * @noinspection PhpDocMissingThrowsInspection
153
     *
154
     * Returns the query's criteria attributes.
155
     *
156
     * @return string[]
157
     */
158
    public function criteriaAttributes(): array
159
    {
160
        // By default, include all public, non-static properties that were defined by a sub class, and certain ones
161
        // in this class
162
        /** @noinspection PhpUnhandledExceptionInspection */
163
        $class = new \ReflectionClass($this);
164
        $names = [];
165
166
        foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
167
            if (!$property->isStatic()) {
168
                $dec = $property->getDeclaringClass();
169
                if (($dec->getName() === self::class || $dec->isSubclassOf(self::class))
170
                ) {
171
                    $names[] = $property->getName();
172
                }
173
            }
174
        }
175
176
        return $names;
177
    }
178
}
179