Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 57
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
Transient
0.00% covered (danger)
0.00%
0 / 57
0.00% covered (danger)
0.00%
0 / 7
420
0.00% covered (danger)
0.00%
0 / 1
 key
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 set
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 get
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
42
 delete_expired
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
20
 delete_by_prefix
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
6
 delete_bulk
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
20
 delete
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Transients for Jetpack Boost.
4 *
5 * @package automattic/jetpack-boost-core
6 */
7
8namespace Automattic\Jetpack\Boost_Core\Lib;
9
10/**
11 * Class Transient
12 */
13class Transient {
14
15    const OPTION_PREFIX = 'jb_transient_';
16
17    /**
18     * Get the key with prefix.
19     *
20     * @param string $key the key to be prefixed.
21     */
22    public static function key( $key ) {
23        return static::OPTION_PREFIX . $key;
24    }
25
26    /**
27     * Updates a cache entry. Creates the cache entry if it doesn't exist.
28     *
29     * @param string $key    Cache key name.
30     * @param mixed  $value  Cache value.
31     * @param int    $expiry Cache expiration in seconds.
32     *
33     * @return void
34     */
35    public static function set( $key, $value, $expiry = 0 ) {
36        if ( 0 === $expiry ) {
37            $expiry = YEAR_IN_SECONDS;
38        }
39
40        $data = array(
41            'expire' => time() + $expiry,
42            'data'   => $value,
43        );
44        update_option( self::key( $key ), $data, false );
45    }
46
47    /**
48     * Gets a cache entry.
49     *
50     * @param string $key     Cache key name.
51     * @param mixed  $default Default value.
52     *
53     * @return mixed
54     */
55    public static function get( $key, $default = null ) {
56        // Ensure everything's there.
57        $option = get_option( self::key( $key ), $default );
58        if ( $default === $option || ! isset( $option['expire'] ) || ! isset( $option['data'] )
59        ) {
60            return $default;
61        }
62
63        // Maybe expire the result instead of returning it.
64        $expire = $option['expire'];
65        $data   = $option['data'];
66        if ( false !== $expire && $expire < time() ) {
67            self::delete( $key );
68
69            return $default;
70        }
71
72        return $data;
73    }
74
75    /**
76     * Delete all expired transients.
77     *
78     * @return int The number of deleted transients.
79     */
80    public static function delete_expired() {
81        global $wpdb;
82
83        //phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
84        $option_names = $wpdb->get_col(
85            $wpdb->prepare(
86                "SELECT option_name FROM $wpdb->options WHERE option_name LIKE %s",
87                self::OPTION_PREFIX . '%'
88            )
89        );
90
91        $count = 0;
92        foreach ( $option_names as $option_name ) {
93            $value = get_option( $option_name );
94            if ( isset( $value['expire'] ) && $value['expire'] < time() ) {
95                delete_option( $option_name );
96                ++$count;
97            }
98        }
99
100        return $count;
101    }
102
103    /**
104     * Delete all `Transient` values with certain prefix from database.
105     *
106     * @param string $prefix Cache key prefix.
107     */
108    public static function delete_by_prefix( $prefix ) {
109        global $wpdb;
110
111        /**
112         * The prefix used in option_name.
113         */
114        $option_prefix = static::key( $prefix );
115
116        /**
117         * LIKE search pattern for the delete query.
118         */
119        $prefix_search_pattern = $wpdb->esc_like( $option_prefix ) . '%';
120
121        //phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
122        $option_names = $wpdb->get_col(
123            $wpdb->prepare(
124                "
125                    SELECT option_name
126                    FROM   $wpdb->options
127                    WHERE  `option_name` LIKE %s
128                ",
129                $prefix_search_pattern
130            )
131        );
132        // phpcs:enable
133
134        // Go through each option individually to ensure caches are handled properly.
135        foreach ( $option_names as $option_name ) {
136            delete_option( $option_name );
137        }
138    }
139
140    /**
141     * Delete all `Transient` values from the database.
142     *
143     * @return void
144     */
145    public static function delete_bulk() {
146        global $wpdb;
147
148        $prefix_search_pattern = $wpdb->esc_like( self::OPTION_PREFIX ) . '%';
149
150        //phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
151        $wpdb->query(
152            $wpdb->prepare(
153                "DELETE FROM $wpdb->options WHERE option_name LIKE %s",
154                $prefix_search_pattern
155            )
156        );
157
158        if (
159            function_exists( 'wp_cache_flush_group' ) &&
160            function_exists( 'wp_cache_supports' ) &&
161            wp_cache_supports( 'flush_group' )
162        ) {
163            wp_cache_flush_group( 'options' );
164        }
165    }
166
167    /**
168     * Delete a cache entry.
169     *
170     * @param string $key Cache key name.
171     *
172     * @return void
173     */
174    public static function delete( $key ) {
175        delete_option( self::key( $key ) );
176    }
177}