Transient_Cache::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 2
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
6
/**
7
 * The WordPress transient driver for the PinkCrab Peristant Cache interface.
8
 *
9
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
12
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
13
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
14
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
15
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
16
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
17
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
19
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20
 *
21
 * @author Glynn Quelch <[email protected]>
22
 * @license http://www.opensource.org/licenses/mit-license.html  MIT License
23
 * @package PinkCrab\WP_PSR16_Cache
24
 */
25
26
namespace PinkCrab\WP_PSR16_Cache;
27
28
use stdClass;
29
use DateInterval;
30
use InvalidArgumentException;
31
use Psr\SimpleCache\CacheInterface;
32
use PinkCrab\WP_PSR16_Cache\CacheInterface_Trait;
33
34
class Transient_Cache implements CacheInterface {
35
36
	/**
37
	 * @uses CacheInterface_Trait::is_valid_key_value()
38
	 * @uses CacheInterface_Trait::ttl_to_seconds()
39
	 * @uses CacheInterface_Trait::all_true()
40
	 */
41
	use CacheInterface_Trait;
42
43
	/**
44
	 * Postfix to wrap any group key.
45
	 */
46
	const CACHE_KEY_POSTFIX = '_';
47
48
	/**
49
	 * The group used for the keys being set/get
50
	 *
51
	 * @var string|null
52
	 */
53
	protected $group = '';
54
55
	/**
56
	 * Creates an instance of the Transient Cache.
57
	 *
58
	 * @param string|null $group
59
	 */
60
	public function __construct( ?string $group = null ) {
61
		$this->group = $group;
62
	}
63
64
	/**
65
	 * Sets a key.
66
	 * Used to conform with Psr\Simple-Cache
67
	 *
68
	 * @param string                 $key   The key of the item to store.
69
	 * @param mixed                  $value The value of the item to store, must be serializable.
70
	 * @param null|int|\DateInterval $ttl
71
	 * @return bool
72
	 * @throws InvalidArgumentException
73
	 */
74
	public function set( $key, $value, $ttl = null ) {
75
		if ( ! $this->is_valid_key_value( $key ) ) {
76
			return false;
77
		}
78
		return \set_transient(
79
			$this->parse_key( $key ),
80
			$value,
81
			$this->ttl_to_seconds( $ttl )
82
		);
83
	}
84
85
	/**
86
	 * Attempts to get from cache, return defualt if nothing returned.
87
	 *
88
	 * @param string $key
89
	 * @param mixed $default
90
	 * @return mixed
91
	 * @throws InvalidArgumentException
92
	 */
93
	public function get( $key, $default = null ) {
94
		if ( ! $this->is_valid_key_value( $key ) ) {
95
			return $default;
96
		}
97
		return \get_transient( $this->parse_key( $key ) ) ?: $default;
98
	}
99
100
	/**
101
	 * Clears a defined cached instance.
102
	 *
103
	 * @param string $key
104
	 * @return bool
105
	 * @throws InvalidArgumentException
106
	 */
107
	public function delete( $key ) {
108
		if ( ! $this->is_valid_key_value( $key ) ) {
109
			return false;
110
		}
111
		return \delete_transient( $this->parse_key( $key ) );
112
	}
113
114
	/**
115
	 * Clears all transients for the defined group.
116
	 *
117
	 * @return bool
118
	 */
119
	public function clear() {
120
		$results = array_map(
121
			function( $e ) {
122
				return \delete_transient( $this->parse_key( $e ) );
123
			},
124
			$this->get_group_keys()
125
		);
126
		return ! \in_array( false, $results, true );
127
	}
128
129
	/**
130
	 * Gets multiple cache values based on an array of keys.
131
	 *
132
	 * @param array<int, string> $keys
133
	 * @param mixed $default
134
	 * @return array<string, mixed>
135
	 */
136
	public function getMultiple( $keys, $default = null ) {
137
		return array_reduce(
138
			$keys,
139
			function( $carry, $key ) use ( $default ) {
140
				$carry[ $key ] = $this->get( $key, $default );
141
				return $carry;
142
			},
143
			array()
144
		);
145
	}
146
147
	/**
148
	 * Sets multiple keys based ona  key => value array.
149
	 *
150
	 * @param array<string, mixed> $values
151
	 * @param DateInterval|int|null $ttl
152
	 * @return bool
153
	 */
154
	public function setMultiple( $values, $ttl = null ) {
155
		return $this->all_true(
156
			array_reduce(
157
				array_keys( $values ),
158
				function( $carry, $key ) use ( $values, $ttl ) {
159
					$carry[ $key ] = $this->set( $key, $values[ $key ], $ttl );
160
					return $carry;
161
				},
162
				array()
163
			)
164
		);
165
	}
166
167
	/**
168
	 * Deletes multiple keys based on an arrya of keys.
169
	 *
170
	 * @param array<int, string> $keys
171
	 * @return bool
172
	 */
173
	public function deleteMultiple( $keys ) {
174
		return $this->all_true(
175
			array_reduce(
176
				$keys,
177
				function( $carry, $key ) {
178
					$carry[ $key ] = $this->delete( $key );
179
					return $carry;
180
				},
181
				array()
182
			)
183
		);
184
	}
185
186
	/**
187
	 * Checks if a key is defined in transient.
188
	 *
189
	 * @param string $key
190
	 * @return bool
191
	 */
192
	public function has( $key ) {
193
		return ! is_null( $this->get( $key ) );
194
	}
195
196
	/**
197
	 * Sets the key basd on the group
198
	 *
199
	 * @param string $key
200
	 * @return string
201
	 */
202
	protected function parse_key( string $key ): string {
203
		return \sprintf(
204
			'%s%s',
205
			$this->group_key_prefix(),
206
			$key
207
		);
208
	}
209
210
	/**
211
	 * Sets the defined prefix to keys.
212
	 *
213
	 * @return string
214
	 */
215
	protected function group_key_prefix(): string {
216
		return $this->group
217
			? $this->group . self::CACHE_KEY_POSTFIX
218
			: '';
219
	}
220
221
	/**
222
	 * Returns all keys that match for this group.
223
	 *
224
	 * @return array<int, string>
225
	 */
226
	protected function get_group_keys(): array {
227
		// Extract the base cache keys (excluding pre/postfixes)
228
		return array_map(
229
			function( $key ) {
230
				return \str_replace(
231
					'_transient_' . $this->group_key_prefix(),
232
					'',
233
					(string) $key
234
				);
235
			},
236
			$this->get_transients()
237
		);
238
	}
239
240
	/**
241
	 * Gets all transients with a matching
242
	 *
243
	 * @uses global $wpdb
244
	 * @return array<int, string>
245
	 */
246
	protected function get_transients(): array {
247
		global $wpdb;
248
249
		return $wpdb->get_col(
250
			$wpdb->prepare(
251
				"SELECT option_name AS name, option_value AS value FROM {$wpdb->options} WHERE option_name LIKE %s",
252
				'_transient_' . $this->group_key_prefix() . '%'
253
			)
254
		);
255
	}
256
}
257