PluginProbe
Customify / 2.5.2
Customify v2.5.2
2.10.9 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.7.1 1.3.0 1.3.1 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.6.0 1.6.0.1 1.6.5 1.7.0 1.7.1 All 77 releases
customify / includes / lib / class-customify-design-assets.php

class-customify-design-assets.php in Customify 2.5.2, at includes/lib/class-customify-design-assets.php

260 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * This is the class that handles the overall logic for design assets.
4 *
5 * @see https://pixelgrade.com
6 * @author Pixelgrade
7 * @since 1.7.4
8 */
9
10 if ( ! defined( 'ABSPATH' ) ) {
11 exit; // Exit if accessed directly
12 }
13
14 if ( ! class_exists( 'Customify_Design_Assets' ) ) {
15
16 class Customify_Design_Assets {
17
18 /**
19 * Holds the only instance of this class.
20 * @var null|Customify_Design_Assets
21 * @access protected
22 * @since 1.7.4
23 */
24 protected static $_instance = null;
25
26 /**
27 * The current design assets config.
28 * @var array
29 * @access public
30 * @since 1.7.4
31 */
32 protected $design_assets = null;
33
34 /**
35 * The cloud API object used to communicate with the cloud.
36 * @var Customify_Cloud_Api
37 * @access public
38 * @since 1.7.4
39 */
40 protected $cloud_api = null;
41
42 /**
43 * Constructor.
44 *
45 * @since 1.7.4
46 */
47 private function __construct() {
48 $this->init();
49 }
50
51 /**
52 * Initialize this module.
53 *
54 * @since 1.7.4
55 */
56 public function init() {
57 /**
58 * Initialize the Cloud API logic.
59 */
60 require_once 'class-customify-cloud-api.php';
61 $this->cloud_api = new Customify_Cloud_Api();
62
63 /*
64 * Handle the force clearing of the caches. We clear in a proactive manner.
65 */
66 add_action( 'activated_plugin', array( $this, 'invalidate_cache' ), 1 );
67 add_action( 'deactivated_plugin', array( $this, 'invalidate_cache' ), 1 );
68 add_action( 'switch_theme', array( $this, 'invalidate_cache' ), 1 );
69 add_action( 'upgrader_process_complete', array( $this, 'invalidate_cache' ), 1 );
70 }
71
72 /**
73 * Get the design assets configuration.
74 *
75 * @since 1.7.4
76 *
77 * @param bool $skip_cache Optional. Whether to use the cached config or fetch a new one.
78 *
79 * @return array
80 */
81 public function get( $skip_cache = false ) {
82 if ( ! is_null( $this->design_assets ) && false === $skip_cache ) {
83 return $this->design_assets;
84 }
85
86 $this->design_assets = $this->maybe_fetch( $skip_cache );
87
88 // Determine if we should use the config in the theme root and skip the external config entirely.
89 if ( defined('CUSTOMIFY_SM_LOAD_THEME_ROOT_CONFIG') && true === CUSTOMIFY_SM_LOAD_THEME_ROOT_CONFIG ) {
90 $this->design_assets = $this->maybe_load_theme_config_from_theme_root( $this->design_assets );
91 }
92
93 return apply_filters( 'customify_style_manager_get_design_assets', $this->design_assets );
94 }
95
96 /**
97 * Fetch the design assets data from the Pixelgrade Cloud.
98 *
99 * Caches the data for 12 hours. Use local defaults if not available.
100 *
101 * @since 1.7.4
102 *
103 * @param bool $skip_cache Optional. Whether to use the cached data or fetch a new one.
104 *
105 * @return array|false
106 */
107 protected function maybe_fetch( $skip_cache = false ) {
108 // First try and get the cached data
109 $data = get_option( $this->get_cache_key() );
110
111 // For performance reasons, we will ONLY fetch remotely when in the WP ADMIN area or via an ADMIN AJAX call, regardless of settings.
112 if ( ! is_admin() ) {
113 return $data;
114 }
115
116 // We don't force skip the cache for AJAX requests for performance reasons.
117 if ( ! wp_doing_ajax() && defined('CUSTOMIFY_SM_ALWAYS_FETCH_DESIGN_ASSETS' ) && true === CUSTOMIFY_SM_ALWAYS_FETCH_DESIGN_ASSETS ) {
118 $skip_cache = true;
119 }
120
121 $expire_timestamp = false;
122
123 // Only try to get the expire timestamp if we really need to.
124 if ( true !== $skip_cache && false !== $data ) {
125 // Get the cache data expiration timestamp.
126 $expire_timestamp = get_option( $this->get_cache_key() . '_timestamp' );
127 }
128
129 // The data isn't set, is expired or we were instructed to skip the cache; we need to fetch fresh data.
130 if ( true === $skip_cache || false === $data || false === $expire_timestamp || $expire_timestamp < time() ) {
131 // Fetch the design assets from the cloud.
132 $fetched_data = $this->cloud_api->fetch_design_assets();
133 // Bail in case of failure to retrieve data.
134 // We will return the data already available.
135 if ( false === $fetched_data ) {
136 return $data;
137 }
138
139 $data = $fetched_data;
140
141 if ( true !== $skip_cache ) {
142 // Cache the data in an option for 6 hours
143 update_option( $this->get_cache_key(), $data, true );
144 update_option( $this->get_cache_key() . '_timestamp', time() + 6 * HOUR_IN_SECONDS, true );
145 }
146 }
147
148 return apply_filters( 'customify_style_manager_maybe_fetch_design_assets', $data );
149 }
150
151 /**
152 * Get the design assets cache key.
153 *
154 * @since 1.7.4
155 *
156 * @return string
157 */
158 private function get_cache_key() {
159 return 'customify_style_manager_design_assets';
160 }
161
162 public function invalidate_cache() {
163 update_option( $this->get_cache_key() . '_timestamp' , time() - 24 * HOUR_IN_SECONDS, true );
164 }
165
166 /**
167 * Include the customify "external" config file in the theme root and overwrite the existing theme configs.
168 *
169 * @since 1.7.4
170 *
171 * @param array $design_assets
172 *
173 * @return array
174 */
175 protected function maybe_load_theme_config_from_theme_root( $design_assets ) {
176 $file_name = 'customify_theme_root.php';
177
178 // First gather details about the current (parent) theme.
179 $theme = wp_get_theme( get_template() );
180 // Bail if for some strange reason we couldn't find the theme.
181 if ( ! $theme->exists() ) {
182 return $design_assets;
183 }
184
185 $file = trailingslashit( $theme->get_template_directory() ) . $file_name;
186 if ( ! file_exists( $file ) ) {
187 return $design_assets;
188 }
189
190 // We expect to get from the file include a $config variable with the entire Customify (partial) config.
191 include $file;
192
193 if ( ! isset( $config ) || ! is_array( $config ) || empty( $config['sections'] ) ) {
194 // Alert the developers that things are not alright.
195 _doing_it_wrong( __METHOD__, 'The Customify theme root config is not good - the `sections` entry is missing. Please check it! We will not apply it.', null );
196
197 return $design_assets;
198 }
199
200 // Construct the pseudo-external theme config.
201 // Start with a clean slate.
202 $design_assets['theme_configs'] = array();
203
204 $design_assets['theme_configs']['theme_root'] = array(
205 'id' => 1,
206 'name' => $theme->get( 'Name' ),
207 'slug' => $theme->get_stylesheet(),
208 'txtd' => $theme->get( 'TextDomain' ),
209 'loose_match' => true,
210 'config' => $config,
211 'created' => date('Y-m-d H:i:s'),
212 'last_modified' => date('Y-m-d H:i:s'),
213 'hashid' => 'theme_root',
214 );
215
216 return $design_assets;
217 }
218
219 /**
220 * Main Customify_Design_Assets Instance
221 *
222 * Ensures only one instance of Customify_Design_Assets is loaded or can be loaded.
223 *
224 * @since 1.7.4
225 * @static
226 *
227 * @return Customify_Design_Assets Main Customify_Design_Assets instance
228 */
229 public static function instance() {
230
231 if ( is_null( self::$_instance ) ) {
232 self::$_instance = new self();
233 }
234
235 return self::$_instance;
236 } // End instance ()
237
238 /**
239 * Cloning is forbidden.
240 *
241 * @since 1.7.4
242 */
243 public function __clone() {
244
245 _doing_it_wrong( __FUNCTION__,esc_html__( 'You should not do that!', 'customify' ), null );
246 }
247
248 /**
249 * Unserializing instances of this class is forbidden.
250 *
251 * @since 1.7.4
252 */
253 public function __wakeup() {
254
255 _doing_it_wrong( __FUNCTION__, esc_html__( 'You should not do that!', 'customify' ), null );
256 }
257 }
258
259 }
260