PluginProbe
Tiered Pricing Table for WooCommerce / 8.1.0
Tiered Pricing Table for WooCommerce v8.1.0
8.1.0 8.0.2 7.1.7 7.1.5 7.1.4 7.1.1 6.5.0 6.4.0 6.1.0 trunk 1.0 1.1 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.3.0 2.3.1 2.3.2 All 92 releases
tier-pricing-table / src / Core / Cache.php

Cache.php in Tiered Pricing Table for WooCommerce 8.1.0, at src/Core/Cache.php

152 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php namespace TierPricingTable\Core;
2
3 /*
4 * Class Cache
5 *
6 * @package TierPricingTable\Core
7 */
8
9 use TierPricingTable\TierPricingTablePlugin;
10 use WC_Product;
11 use WC_Product_Variable;
12
13 class Cache {
14
15 use ServiceContainerTrait;
16
17 protected $variableProductsHashes = array();
18
19 const PURGE_CACHE_ACTION = 'tpt_purge_cache';
20 const PRODUCT_DATA_TRANSIENT_KEY = 'tpt_product_data';
21
22 protected $isEnabled = true;
23
24 public function __construct() {
25
26 $this->isEnabled = $this->getContainer()->getSettings()->get( 'cache_enabled', 'yes' ) === 'yes';
27
28 // The purge action must be available even when caching is disabled: the "Purge cache" button is always
29 // rendered, and a stale transient left over from when caching was enabled must be removable.
30 add_action( 'admin_post_' . self::PURGE_CACHE_ACTION, array( $this, 'handlePurgeRequest' ) );
31
32 if ( ! $this->isEnabled ) {
33 return;
34 }
35
36 // Store variable products price hashes
37 add_filter( 'woocommerce_get_variation_prices_hash', function ( $hash, WC_Product_Variable $product ) {
38 $pricesDisplayType = ServiceContainer::getInstance()->getSettings()->get( 'tiered_price_at_catalog_type',
39 'range' );
40
41 $hash[] = $product->get_date_modified();
42 $hash[] = $product->get_id();
43
44 if ( ! array_key_exists( $product->get_id(), $this->variableProductsHashes ) ) {
45 $this->variableProductsHashes[ $product->get_id() ] = md5( wp_json_encode( $hash ) . $pricesDisplayType );
46 }
47
48 return $hash;
49 }, 999999, 2 );
50 }
51
52 public function handlePurgeRequest() {
53
54 $nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( $_REQUEST['nonce'] ) : false;
55
56 if ( current_user_can( 'manage_options' ) && wp_verify_nonce( $nonce, self::PURGE_CACHE_ACTION ) ) {
57
58 ServiceContainer::getInstance()->getAdminNotifier()->flash( __( 'Cache has been purged successfully',
59 'tier-pricing-table' ) );
60
61 $this->purge();
62 }
63
64 wp_safe_redirect( wp_get_referer() ? wp_get_referer() : admin_url() );
65 exit;
66 }
67
68 /**
69 * Read the stored product data. A missing transient returns false, which "(array) false" would turn into
70 * array( 0 => false ), so normalize explicitly.
71 */
72 protected function readStoredData(): array {
73 $data = get_transient( self::PRODUCT_DATA_TRANSIENT_KEY );
74
75 return is_array( $data ) ? $data : array();
76 }
77
78 public function isEnabled(): bool {
79 return $this->getContainer()->getSettings()->get( 'cache_enabled', 'yes' ) === 'yes';
80 }
81
82 public function getProductCacheKey( WC_Product $product ) {
83
84 if ( TierPricingTablePlugin::isVariableProductSupported( $product ) ) {
85
86 if ( ! empty( $this->variableProductsHashes[ $product->get_id() ] ) ) {
87 return $this->variableProductsHashes[ $product->get_id() ];
88 }
89 }
90
91 // add-ons whose pricing changes without the product changing (scheduled global rules, for instance) salt the key
92 $salt = (string) apply_filters( 'tiered_pricing_table/cache/product_cache_key_salt', '', $product );
93
94 return md5( $product->get_date_modified() . implode( ',', TierPricingTablePlugin::getCurrentUserRoles() ) . $salt );
95 }
96
97 public function getProductData( WC_Product $product, $key = null ) {
98 if ( ! $this->isEnabled ) {
99 return false;
100 }
101
102 $productCacheKey = $this->getProductCacheKey( $product );
103
104 $data = $this->readStoredData();
105
106 if ( empty( $data[ $productCacheKey ] ) ) {
107 return false;
108 }
109
110 if ( $key ) {
111 return $data[ $productCacheKey ][ $key ] ?? false;
112 }
113
114 return $data;
115 }
116
117 public function setProductData( WC_Product $product, $key, $value ) {
118
119 if ( ! $this->isEnabled ) {
120 return;
121 }
122
123 $productCacheKey = $this->getProductCacheKey( $product );
124
125 $data = $this->readStoredData();
126
127 if ( $key ) {
128 $data[ $productCacheKey ][ $key ] = $value;
129 } else {
130 $data[ $productCacheKey ] = $value;
131 }
132
133 set_transient( self::PRODUCT_DATA_TRANSIENT_KEY, $data, DAY_IN_SECONDS * 10 + rand( 10, DAY_IN_SECONDS ) );
134 }
135
136 public function purge( $product = null ) {
137
138 if ( $product ) {
139 $this->setProductData( $product, null, null );
140 } else {
141 delete_transient( self::PRODUCT_DATA_TRANSIENT_KEY );
142 }
143 }
144
145 public function getPurgeURL(): string {
146 return add_query_arg( array(
147 'action' => self::PURGE_CACHE_ACTION,
148 'nonce' => wp_create_nonce( self::PURGE_CACHE_ACTION ),
149 ), admin_url( 'admin-post.php' ) );
150 }
151 }
152