PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 4.5.0
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v4.5.0
4.5.1 4.5.0 4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.11.1 1.11.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.13.0 2.14.0 2.14.1 2.15.0 2.15.1 2.16.0 2.16.1 2.16.2 2.16.3 2.17.0 2.17.1 2.17.2 2.18.0 2.19.0 2.19.2 2.19.3 2.19.4 2.2.0 2.2.1 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.26.0 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.2 2.29.3 2.29.4 2.3.0 2.3.1 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.40.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.9.0 3.0.0 3.0.0-RC1 3.0.0-RC2 3.0.0-beta1 3.0.0-beta2 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.10.0 3.10.1 3.11.0 3.12.0 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.14.0 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.16.6 3.16.7 3.16.8 3.17.0 3.17.1 3.17.2 3.17.3 3.17.4 3.17.5 3.17.6 3.18.0 3.19.0 3.19.1 3.19.2 3.2.0 3.2.1 3.2.2 3.20.0 3.20.1 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 trunk 4.1.0 0.2.19.1 4.1.1 1.0.0 4.2.0 1.0.1 1.0.2
surecart / app / src / WordPress / Cache / CacheService.php
surecart / app / src / WordPress / Cache Last commit date
CacheService.php 2 weeks ago CacheServiceProvider.php 2 weeks ago DoNotCachePageService.php 2 weeks ago LiteSpeedCacheService.php 4 months ago W3TotalCacheService.php 4 months ago WpFastestCacheService.php 4 months ago
CacheService.php
254 lines
1 <?php
2
3 namespace SureCart\WordPress\Cache;
4
5 /**
6 * Abstract Cache Service.
7 */
8 abstract class CacheService {
9 /**
10 * Bootstrap the service.
11 *
12 * @return void
13 */
14 public function bootstrap() {
15 // Early return if the cache plugin is not active.
16 if ( ! $this->isCachePluginActive() ) {
17 return;
18 }
19
20 // Disable cache for SureCart dynamic pages.
21 add_action( 'wp', [ $this, 'maybeDisableCache' ] );
22
23 // Disable cache for SureCart REST API requests.
24 add_action( 'rest_api_init', [ $this, 'maybeDisableCacheForRestApi' ], 1 );
25
26 // Purge cache when product stock is adjusted.
27 add_action( 'surecart/product_stock_adjusted', [ $this, 'purgeProductCacheOnStockAdjustment' ] );
28 }
29
30 /**
31 * Disable cache for the current page.
32 *
33 * @param string $reason Reason for disabling cache.
34 * @return void
35 */
36 abstract protected function disableCache( string $reason ): void;
37
38 /**
39 * Check if the cache plugin is active.
40 *
41 * @return bool
42 */
43 abstract protected function isCachePluginActive(): bool;
44
45 /**
46 * Check if the current page should be excluded from cache.
47 *
48 * @return bool
49 */
50 public function shouldExcludeFromCache(): bool {
51 return $this->isCustomerDashboardPage()
52 || $this->isCheckoutPage()
53 || $this->hasCheckoutFormBlock()
54 || $this->isBuyPage();
55 }
56
57 /**
58 * Maybe disable cache for SureCart dynamic pages.
59 *
60 * @return void
61 */
62 public function maybeDisableCache() {
63 if ( $this->isCustomerDashboardPage() ) {
64 $this->disableCacheWithBrowserHeaders( 'SureCart customer dashboard' );
65 return;
66 }
67
68 if ( $this->isCheckoutPage() ) {
69 $this->disableCacheWithBrowserHeaders( 'SureCart checkout page' );
70 return;
71 }
72
73 if ( $this->hasCheckoutFormBlock() ) {
74 $this->disableCacheWithBrowserHeaders( 'SureCart checkout form block' );
75 return;
76 }
77
78 if ( $this->isBuyPage() ) {
79 $this->disableCacheWithBrowserHeaders( 'SureCart buy page' );
80 return;
81 }
82 }
83
84 /**
85 * Disable both server-side and browser caching.
86 *
87 * @param string $reason Reason for disabling cache.
88 * @return void
89 */
90 protected function disableCacheWithBrowserHeaders( string $reason ): void {
91 // Disable server-side caching via the cache plugin.
92 $this->disableCache( $reason );
93
94 // Disable browser caching by sending no-cache headers.
95 if ( ! headers_sent() ) {
96 nocache_headers();
97 }
98 }
99
100 /**
101 * Maybe disable cache for SureCart REST API requests.
102 *
103 * @return void
104 */
105 public function maybeDisableCacheForRestApi() {
106 if ( $this->isSureCartRestRequest() ) {
107 $this->disableCacheWithBrowserHeaders( 'SureCart REST API request' );
108 }
109 }
110
111 /**
112 * Check if the current request is a SureCart REST API request.
113 *
114 * @return bool
115 */
116 protected function isSureCartRestRequest(): bool {
117 $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
118
119 if ( strpos( $request_uri, '/surecart/' ) !== false && strpos( $request_uri, 'wp-json' ) !== false ) {
120 return true;
121 }
122
123 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
124 $rest_route = isset( $_GET['rest_route'] ) ? sanitize_text_field( wp_unslash( $_GET['rest_route'] ) ) : '';
125 if ( strpos( $rest_route, '/surecart/' ) !== false ) {
126 return true;
127 }
128
129 return false;
130 }
131
132 /**
133 * Purge product cache when stock is adjusted.
134 *
135 * @param \SureCart\Models\Product $product The product model.
136 * @return void
137 */
138 public function purgeProductCacheOnStockAdjustment( $product ) {
139 // Override in child classes if needed.
140 }
141
142 /**
143 * Check if the current page is the customer dashboard page.
144 *
145 * Uses is_page() instead of a URL comparison so dashboard subviews
146 * with query args (?action=index&model=invoice) are also matched.
147 *
148 * @return bool
149 */
150 protected function isCustomerDashboardPage(): bool {
151 $dashboard_page_id = \SureCart::pages()->getId( 'dashboard' );
152
153 if ( empty( $dashboard_page_id ) ) {
154 return false;
155 }
156
157 return is_page( $dashboard_page_id );
158 }
159
160 /**
161 * Check if the current page is the checkout page.
162 *
163 * @return bool
164 */
165 protected function isCheckoutPage(): bool {
166 $checkout_page_id = \SureCart::pages()->getId( 'checkout' );
167
168 if ( empty( $checkout_page_id ) ) {
169 return false;
170 }
171
172 return is_page( $checkout_page_id );
173 }
174
175 /**
176 * Check if the current page has a checkout form block.
177 *
178 * @return bool
179 */
180 protected function hasCheckoutFormBlock(): bool {
181 $post = get_post();
182
183 if ( ! $post ) {
184 return false;
185 }
186
187 return has_block( 'surecart/checkout-form', $post ) || has_block( 'surecart/form', $post );
188 }
189
190 /**
191 * Check if the current page is a buy page.
192 *
193 * Pretty buy permalinks (/buy/{product-slug}/) rewrite to the
194 * sc_checkout_product_id query var; sc-buy covers legacy buy links.
195 *
196 * @return bool
197 */
198 protected function isBuyPage(): bool {
199 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
200 return isset( $_GET['sc-buy'] )
201 || ! empty( get_query_var( 'sc-buy' ) )
202 || ! empty( get_query_var( 'sc_checkout_product_id' ) );
203 }
204
205 /**
206 * Get SureCart vary cookies.
207 *
208 * @return array
209 */
210 protected function getVaryCookies(): array {
211 $cookies = [
212 'sc_checkout_id',
213 'sc_customer_id',
214 'sc_order_id',
215 ];
216
217 /**
218 * Filter the SureCart cookies used for cache variation.
219 *
220 * @param array $cookies Array of cookie names.
221 */
222 return apply_filters( 'surecart/cache/vary_cookies', $cookies );
223 }
224
225 /**
226 * Get core WordPress scripts that should be excluded from JS defer.
227 *
228 * @return array
229 */
230 protected function getJsDeferExcludes(): array {
231 $scripts = [
232 'wp-api-fetch',
233 'wp-a11y',
234 'wp-i18n',
235 'wp-url',
236 'dom-ready',
237 'wp-hooks',
238 'api-fetch',
239 'a11y.min.js',
240 'i18n.min.js',
241 'url.min.js',
242 'dom-ready.min.js',
243 'hooks.min.js',
244 ];
245
246 /**
247 * Filter the scripts excluded from JS defer.
248 *
249 * @param array $scripts Array of script patterns to exclude.
250 */
251 return apply_filters( 'surecart/cache/js_defer_excludes', $scripts );
252 }
253 }
254