Skip to content

Commit 2890c32

Browse files
committed
Merge branch 'main' into develop
2 parents 01292df + f077c1d commit 2890c32

File tree

11 files changed

+624
-13
lines changed

11 files changed

+624
-13
lines changed

composer.lock

Lines changed: 7 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

phpstan-stubs/wordpress.php.stub

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
function __( string $message, string $domain = '' ): string {
4+
return '';
5+
}

phpstan.dist.neon

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ includes:
22
- vendor/szepeviktor/phpstan-wordpress/extension.neon
33

44
parameters:
5-
#editorUrl: 'phpstorm://open?file=%%file%%&line=%%line%%'
5+
editorUrl: 'phpstorm://open?file=%%file%%&line=%%line%%'
66
level: 5
77
paths:
88
- src
@@ -16,6 +16,7 @@ parameters:
1616

1717
scanFiles:
1818
- datakit.php
19+
- phpstan-stubs/wordpress.php.stub # Scanned because as a stub this file does not work.
1920

2021
# ignoreErrors:
2122
# -

src/Cache/WordPressCacheProvider.php

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
<?php
2+
3+
namespace DataKit\Plugin\Cache;
4+
5+
use DataKit\DataViews\Cache\BaseCacheProvider;
6+
use DataKit\DataViews\Cache\CacheItem;
7+
use DateInterval;
8+
use Exception;
9+
10+
/**
11+
* A cache provider backed by WordPress' Option API.
12+
*
13+
* @since $ver$
14+
*/
15+
final class WordPressCacheProvider extends BaseCacheProvider {
16+
/**
17+
* A prefix that indicates the cache item is for this cache provider.
18+
*
19+
* @since $ver$
20+
*/
21+
private const CACHE_KEY_PREFIX = 'DATAKIT_ITEM';
22+
23+
/**
24+
* A prefix that indicates the cache item is a tag.
25+
*
26+
* @since $ver$
27+
*/
28+
private const TAG_PREFIX = 'DATAKIT_TAG';
29+
30+
/**
31+
* Micro cache of cache items.
32+
*
33+
* @since $ver$
34+
*
35+
* @var array<string, CacheItem>
36+
*/
37+
private array $items = [];
38+
39+
/**
40+
* Returns a normalized cache key.
41+
*
42+
* @since $ver$
43+
*
44+
* @param string $key The original key.
45+
*
46+
* @return string THe normalized key.
47+
*/
48+
private function normalize_key( string $key, string $type = 'item' ): string {
49+
return sprintf( '%s_%s', 'item' === $type ? self::CACHE_KEY_PREFIX : self::TAG_PREFIX, $key );
50+
}
51+
52+
/**
53+
* {@inheritDoc}
54+
*
55+
* @since $ver$
56+
*/
57+
public function set( string $key, $value, ?int $ttl = null, array $tags = [] ): void {
58+
try {
59+
$time = (int) $ttl > 0
60+
? ( $this->clock->now()->add( new DateInterval( 'PT' . $ttl . 'S' ) ) )
61+
: null;
62+
} catch ( Exception $e ) {
63+
throw new \InvalidArgumentException( $e->getMessage(), $e->getCode(), $e );
64+
}
65+
66+
update_option( $this->normalize_key( $key ), new CacheItem( $key, $value, $time, $tags ), false );
67+
68+
$this->add_tags( $key, $tags );
69+
}
70+
71+
/**
72+
* Records a key for all provided tags.
73+
*
74+
* @since $ver$
75+
*
76+
* @param string $key The key to tag.
77+
* @param array $tags The tags.
78+
*/
79+
private function add_tags( string $key, array $tags ): void {
80+
foreach ( $tags as $tag ) {
81+
if ( ! is_string( $tag ) ) {
82+
throw new \InvalidArgumentException( 'A tag must be a string.' );
83+
}
84+
85+
$tag_key = $this->normalize_key( $tag, 'tag' );
86+
$tags = (array) get_option( $tag_key, [] );
87+
$tags = array_unique( array_merge( $tags, [ $key ] ) );
88+
89+
update_option( $tag_key, $tags, false );
90+
}
91+
}
92+
93+
/**
94+
* {@inheritDoc}
95+
*
96+
* @since $ver$
97+
*/
98+
protected function doGet( string $key ): ?CacheItem {
99+
if ( ! isset( $this->items[ $key ] ) ) {
100+
$normalized_key = $this->normalize_key( $key );
101+
$this->items[ $key ] = get_option( $normalized_key );
102+
}
103+
104+
$item = $this->items[ $key ] ?? null;
105+
106+
return $item instanceof CacheItem ? $item : null;
107+
}
108+
109+
/**
110+
* {@inheritDoc}
111+
*
112+
* @since $ver$
113+
*/
114+
public function delete( string $key ): bool {
115+
unset( $this->items[ $key ] );
116+
117+
return delete_option( $this->normalize_key( $key ) );
118+
}
119+
120+
/**
121+
* {@inheritDoc}
122+
*
123+
* @since $ver$
124+
*/
125+
public function delete_by_tags( array $tags ): bool {
126+
foreach ( $tags as $tag ) {
127+
$normalized_tag = $this->normalize_key( $tag, 'tag' );
128+
129+
foreach ( (array) get_option( $normalized_tag, [] ) as $item_key ) {
130+
$this->delete( $item_key );
131+
}
132+
133+
delete_option( $normalized_tag );
134+
}
135+
136+
return true;
137+
}
138+
139+
/**
140+
* {@inheritDoc}
141+
*
142+
* @since $ver$
143+
*/
144+
public function clear(): bool {
145+
global $wpdb;
146+
147+
$wpdb->query(
148+
$wpdb->prepare(
149+
"DELETE FROM {$wpdb->options} a WHERE a.option_name LIKE %s OR a.option_name LIKE %s",
150+
$wpdb->esc_like( self::TAG_PREFIX ) . '_%',
151+
$wpdb->esc_like( self::CACHE_KEY_PREFIX ) . '_%',
152+
)
153+
);
154+
155+
return true;
156+
}
157+
}

0 commit comments

Comments
 (0)