PluginProbe
WPGraphQL Smart Cache / 2.3.1
WPGraphQL Smart Cache v2.3.1
2.3.1 2.3.0 2.2.2 2.2.1 2.2.0 trunk 0.3.6 0.3.7 0.3.8 0.3.9 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 1.2.1 1.3.0 1.3.1 1.3.2 All 29 releases
wpgraphql-smart-cache / src / Cache / Query.php

Query.php in WPGraphQL Smart Cache 2.3.1, at src/Cache/Query.php

141 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * For a GraphQL query, look for the results in the WP transient cache and return that.
4 * If not cached, when return results to client, save results to transient cache for future requests.
5 */
6
7 namespace WPGraphQL\SmartCache\Cache;
8
9 use WPGraphQL\SmartCache\Document;
10 use WPGraphQL\SmartCache\Storage\Transient;
11 use WPGraphQL\SmartCache\Storage\WpCache;
12 use WPGraphQL\SmartCache\Storage\Ephemeral;
13
14 class Query {
15
16 const GROUP_NAME = 'gql_cache';
17
18 /**
19 * The storage object for the actual system of choice transient, database, object, memory, etc
20 *
21 * @var WpCache|Transient|Ephemeral
22 **/
23 public static $storage = null;
24
25 /**
26 * The current GraphQL request.
27 *
28 * @var \WPGraphQL\Request|null
29 */
30 protected $request;
31
32 /**
33 * @return void
34 */
35 public function init() {
36 if ( null === self::$storage ) {
37 self::$storage = apply_filters(
38 'graphql_cache_storage_object', //phpcs:ignore
39 wp_using_ext_object_cache() ? new WpCache( self::GROUP_NAME ) : new Transient( self::GROUP_NAME )
40 );
41 }
42 }
43
44 /**
45 * Unique identifier for this request is normalized query string, operation and variables
46 *
47 * @param string|null $query_id queryId from the graphql query request
48 * @param string $query query string
49 * @param array $variables Variables sent with request or null
50 * @param string $operation Name of operation if specified on the request or null
51 *
52 * @return string|false unique id for this request or false if query not provided
53 */
54 public function build_key( $query_id, $query, $variables = null, $operation = null ) {
55 // Unique identifier for this request is normalized query string, operation and variables
56 // If request is by queryId, get the saved query string, which is already normalized
57 if ( $query_id ) {
58 $saved_query = new Document();
59 $query = $saved_query->get( $query_id );
60 } elseif ( $query ) {
61 // Query string provided, normalize it
62 $query_ast = \GraphQL\Language\Parser::parse( $query );
63 $query = \GraphQL\Language\Printer::doPrint( $query_ast );
64 }
65
66 if ( ! $query ) {
67 return false;
68 }
69
70 // Get user ID from AppContext->viewer which is set at Request creation
71 // and doesn't change even if wp_set_current_user(0) is called later.
72 // We intentionally do NOT fall back to wp_get_current_user() because that
73 // function's return value can change mid-request (e.g., when WPGraphQL calls
74 // wp_set_current_user(0) in has_authentication_errors()). Using 0 as fallback
75 // treats the request as unauthenticated, which is the safe default.
76 if ( $this->request ) {
77 $user_id = $this->request->app_context->viewer->ID;
78 } else {
79 $user_id = 0;
80 }
81
82 $parts = [
83 'query' => $query,
84 'variables' => $variables ?: null,
85 'operation' => $operation ?: null,
86 'user' => $user_id,
87 ];
88
89 $parts_string = wp_json_encode( $parts );
90
91 if ( false === $parts_string ) {
92 return false;
93 }
94
95 return hash( 'sha256', $parts_string );
96 }
97
98 /**
99 * Get the data from cache/transient based on the provided key
100 *
101 * @param string $key unique id for this request
102 * @return mixed|array|object|null The graphql response or null if not found
103 */
104 public function get( $key ) {
105 return self::$storage->get( $key );
106 }
107
108 /**
109 * Converts GraphQL query result to spec-compliant serializable array using provided function
110 *
111 * @param string $key unique id for this request
112 * @param mixed|array|object|null $data The graphql response
113 * @param int $expire Time in seconds for the data to persist in cache. Zero means no expiration.
114 *
115 * @return bool False if value was not set and true if value was set.
116 */
117 public function save( $key, $data, $expire = DAY_IN_SECONDS ) {
118 return self::$storage->set( $key, $data, $expire );
119 }
120
121 /**
122 * Delete the data from cache/transient based on the provided key
123 *
124 * @param string $key unique id for this request
125 * @return bool True on successful removal, false on failure.
126 */
127 public function delete( $key ) {
128 return self::$storage->delete( $key );
129 }
130
131 /**
132 * Searches the database for all graphql transients matching our prefix
133 *
134 * @return int|false Count of the number deleted. False if error, nothing to delete or caching not enabled.
135 * @return bool True on success, false on failure.
136 */
137 public function purge_all() {
138 return self::$storage->purge_all();
139 }
140 }
141