Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
69.23% |
27 / 39 |
|
40.00% |
2 / 5 |
CRAP | |
0.00% |
0 / 1 |
Transient | |
69.23% |
27 / 39 |
|
40.00% |
2 / 5 |
23.46 | |
0.00% |
0 / 1 |
should_use_transients | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
get | |
84.62% |
11 / 13 |
|
0.00% |
0 / 1 |
6.13 | |||
set | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
3 | |||
delete | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
12 | |||
__call | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | namespace NewfoldLabs\WP\Module\Data\Helpers; |
3 | |
4 | /** |
5 | * Custom Transient class to handle an Options API based fallback |
6 | */ |
7 | class Transient { |
8 | |
9 | /** |
10 | * Whether to use transients to store temporary data |
11 | * |
12 | * If the site has an object-cache.php drop-in, then we can't reliably |
13 | * use the transients API. We'll try to fall back to the options API. |
14 | */ |
15 | protected static function should_use_transients(): bool { |
16 | require_once constant( 'ABSPATH' ) . '/wp-admin/includes/plugin.php'; |
17 | return ! array_key_exists( 'object-cache.php', get_dropins() ) |
18 | || 'atomic' === \NewfoldLabs\WP\Context\getContext( 'platform' ); // Bluehost Cloud. |
19 | } |
20 | |
21 | /** |
22 | * Wrapper for get_transient() with Options API fallback |
23 | * |
24 | * @see \get_transient() |
25 | * @see \get_option() |
26 | * @see \delete_option() |
27 | * |
28 | * @param string $key The key of the transient to retrieve |
29 | * @return mixed The value of the transient |
30 | */ |
31 | public static function get( string $key ) { |
32 | if ( self::should_use_transients() ) { |
33 | return \get_transient( $key ); |
34 | } |
35 | |
36 | /** |
37 | * Implement the filters as used in {@see get_transient()}. |
38 | */ |
39 | $pre = apply_filters( "pre_transient_{$key}", false, $key ); |
40 | if ( false !== $pre ) { |
41 | return $pre; |
42 | } |
43 | |
44 | /** |
45 | * The saved value and the Unix time it expires at. |
46 | * |
47 | * @var array{value:mixed, expires_at:int} $data |
48 | */ |
49 | $data = \get_option( $key ); |
50 | if ( is_array( $data ) && isset( $data['expires_at'], $data['value'] ) ) { |
51 | if ( $data['expires_at'] > time() ) { |
52 | $value = $data['value']; |
53 | } else { |
54 | \delete_option( $key ); |
55 | $value = false; |
56 | } |
57 | } else { |
58 | /** |
59 | * Set $value to false if $data is not a valid array. |
60 | * This is to prevent PHP notices when trying to access $data['expires_at']. |
61 | */ |
62 | $value = false; |
63 | } |
64 | |
65 | /** |
66 | * Implement the filters as used in {@see get_transient()}. |
67 | */ |
68 | return apply_filters( "transient_{$key}", $value, $key ); |
69 | } |
70 | |
71 | /** |
72 | * Wrapper for set_transient() with Options API fallback |
73 | * |
74 | * @see \set_transient() |
75 | * @see \update_option() |
76 | * |
77 | * @param string $key Key to use for storing the transient |
78 | * @param mixed $value Value to be saved |
79 | * @param integer $expires_in Optional expiration time in seconds from now. Default is 1 hour |
80 | * |
81 | * @return bool Whether the value was saved |
82 | */ |
83 | public static function set( string $key, $value, int $expires_in = 3600 ): bool { |
84 | if ( self::should_use_transients() ) { |
85 | return \set_transient( $key, $value, $expires_in ); |
86 | } |
87 | |
88 | /** |
89 | * Implement the filters as used in {@see set_transient()}. |
90 | */ |
91 | $value = apply_filters( "pre_set_transient_{$key}", $value, $expires_in, $key ); |
92 | $expires_in = apply_filters( "expiration_of_transient_{$key}", $expires_in, $value, $key ); |
93 | |
94 | $data = array( |
95 | 'value' => $value, |
96 | 'expires_at' => $expires_in + time(), |
97 | ); |
98 | |
99 | $result = \update_option( $key, $data, false ); |
100 | |
101 | if ( $result ) { |
102 | do_action( "set_transient_{$key}", $value, $expires_in, $key ); |
103 | do_action( 'setted_transient', $key, $value, $expires_in ); |
104 | } |
105 | |
106 | return $result; |
107 | } |
108 | |
109 | /** |
110 | * Wrapper for delete_transient() with Options API fallback |
111 | * |
112 | * @see \delete_transient() |
113 | * @see \delete_option() |
114 | * |
115 | * @param string $key The key of the transient/option to delete |
116 | * @return bool Whether the value was deleted |
117 | */ |
118 | public static function delete( $key ): bool { |
119 | if ( self::should_use_transients() ) { |
120 | return \delete_transient( $key ); |
121 | } |
122 | |
123 | /** |
124 | * Implement the filters as used in {@see set_transient()}. |
125 | * |
126 | * @param string $key Transient name. |
127 | */ |
128 | do_action( "delete_transient_{$key}", $key ); |
129 | |
130 | $result = \delete_option( $key ); |
131 | |
132 | if ( $result ) { |
133 | |
134 | /** |
135 | * Implement the filters as used in {@see set_transient()}. |
136 | * |
137 | * @param string $transient Deleted transient name. |
138 | */ |
139 | do_action( 'deleted_transient', $key ); |
140 | } |
141 | |
142 | return $result; |
143 | } |
144 | |
145 | /** |
146 | * Make the static functions callable as instance methods. |
147 | * |
148 | * @param string $name The function name being called. |
149 | * @param array $arguments The arguments passed to that function. |
150 | * |
151 | * @return mixed |
152 | * @throws \BadMethodCallException If the method does not exist. |
153 | */ |
154 | public function __call( $name, $arguments ) { |
155 | if ( ! method_exists( __CLASS__, $name ) ) { |
156 | throw new \BadMethodCallException( 'Method ' . esc_html( $name ) . ' does not exist' ); |
157 | } |
158 | return self::$name( ...$arguments ); |
159 | } |
160 | } |