PluginProbe
Customify / 2.7.0
Customify v2.7.0
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.7.0, at includes/lib/class-customify-design-assets.php

254 lines 6.9 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 /**
65 * Get the design assets configuration.
66 *
67 * @since 1.7.4
68 *
69 * @param bool $skip_cache Optional. Whether to use the cached config or fetch a new one.
70 *
71 * @return array
72 */
73 public function get( $skip_cache = false ) {
74 if ( ! is_null( $this->design_assets ) && false === $skip_cache ) {
75 return $this->design_assets;
76 }
77
78 $this->design_assets = $this->maybe_fetch( $skip_cache );
79
80 // Determine if we should use the config in the theme root and skip the external config entirely.
81 if ( defined('CUSTOMIFY_SM_LOAD_THEME_ROOT_CONFIG') && true === CUSTOMIFY_SM_LOAD_THEME_ROOT_CONFIG ) {
82 $this->design_assets = $this->maybe_load_theme_config_from_theme_root( $this->design_assets );
83 }
84
85 return apply_filters( 'customify_style_manager_get_design_assets', $this->design_assets );
86 }
87
88 /**
89 * Fetch the design assets data from the Pixelgrade Cloud.
90 *
91 * Caches the data for 12 hours. Use local defaults if not available.
92 *
93 * @since 1.7.4
94 *
95 * @param bool $skip_cache Optional. Whether to use the cached data or fetch a new one.
96 *
97 * @return array|false
98 */
99 protected function maybe_fetch( $skip_cache = false ) {
100 // First try and get the cached data
101 $data = get_option( self::get_cache_key() );
102
103 // For performance reasons, we will ONLY fetch remotely when in the WP ADMIN area or via an ADMIN AJAX call, regardless of settings.
104 if ( ! is_admin() ) {
105 return $data;
106 }
107
108 // We don't force skip the cache for AJAX requests for performance reasons.
109 if ( ! wp_doing_ajax() && defined('CUSTOMIFY_SM_ALWAYS_FETCH_DESIGN_ASSETS' ) && true === CUSTOMIFY_SM_ALWAYS_FETCH_DESIGN_ASSETS ) {
110 $skip_cache = true;
111 }
112
113 $expire_timestamp = false;
114
115 // Only try to get the expire timestamp if we really need to.
116 if ( true !== $skip_cache && false !== $data ) {
117 // Get the cache data expiration timestamp.
118 $expire_timestamp = get_option( self::get_cache_key() . '_timestamp' );
119 }
120
121 // The data isn't set, is expired or we were instructed to skip the cache; we need to fetch fresh data.
122 if ( true === $skip_cache || false === $data || false === $expire_timestamp || $expire_timestamp < time() ) {
123 // Fetch the design assets from the cloud.
124 $fetched_data = $this->cloud_api->fetch_design_assets();
125 // Bail in case of failure to retrieve data.
126 // We will return the data already available.
127 if ( false === $fetched_data || null === $fetched_data ) {
128 return $data;
129 }
130
131 $data = $fetched_data;
132
133 // Cache the data in an option for 6 hours
134 update_option( self::get_cache_key(), $data, true );
135 update_option( self::get_cache_key() . '_timestamp', time() + 6 * HOUR_IN_SECONDS, true );
136 }
137
138 return apply_filters( 'customify_style_manager_maybe_fetch_design_assets', $data );
139 }
140
141 /**
142 * Get the design assets cache key.
143 *
144 * @since 1.7.4
145 *
146 * @return string
147 */
148 private static function get_cache_key() {
149 return 'customify_style_manager_design_assets';
150 }
151
152 public static function invalidate_cache() {
153 update_option( self::get_cache_key() . '_timestamp' , time() - 24 * HOUR_IN_SECONDS, true );
154 }
155
156 /**
157 * Include the customify "external" config file in the theme root and overwrite the existing theme configs.
158 *
159 * @since 1.7.4
160 *
161 * @param array $design_assets
162 *
163 * @return array
164 */
165 protected function maybe_load_theme_config_from_theme_root( $design_assets ) {
166 $file_name = 'customify_theme_root.php';
167
168 // First gather details about the current (parent) theme.
169 $theme = wp_get_theme( get_template() );
170 // Bail if for some strange reason we couldn't find the theme.
171 if ( ! $theme->exists() ) {
172 return $design_assets;
173 }
174
175 $file = trailingslashit( $theme->get_template_directory() ) . $file_name;
176 if ( ! file_exists( $file ) ) {
177 return $design_assets;
178 }
179
180 // We expect to get from the file include a $config variable with the entire Customify (partial) config.
181 include $file;
182
183 if ( ! isset( $config ) || ! is_array( $config ) || empty( $config['sections'] ) ) {
184 // Alert the developers that things are not alright.
185 _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 );
186
187 return $design_assets;
188 }
189
190 // Construct the pseudo-external theme config.
191 // Start with a clean slate.
192 $design_assets['theme_configs'] = array();
193
194 $design_assets['theme_configs']['theme_root'] = array(
195 'id' => 1,
196 'name' => $theme->get( 'Name' ),
197 'slug' => $theme->get_stylesheet(),
198 'txtd' => $theme->get( 'TextDomain' ),
199 'loose_match' => true,
200 'config' => $config,
201 'created' => date('Y-m-d H:i:s'),
202 'last_modified' => date('Y-m-d H:i:s'),
203 'hashid' => 'theme_root',
204 );
205
206 return $design_assets;
207 }
208
209 /**
210 * Main Customify_Design_Assets Instance
211 *
212 * Ensures only one instance of Customify_Design_Assets is loaded or can be loaded.
213 *
214 * @since 1.7.4
215 * @static
216 *
217 * @return Customify_Design_Assets Main Customify_Design_Assets instance
218 */
219 public static function instance() {
220
221 if ( is_null( self::$_instance ) ) {
222 self::$_instance = new self();
223 }
224
225 return self::$_instance;
226 }
227
228 /**
229 * Cloning is forbidden.
230 *
231 * @since 1.7.4
232 */
233 public function __clone() {
234
235 _doing_it_wrong( __FUNCTION__,esc_html__( 'You should not do that!', 'customify' ), null );
236 }
237
238 /**
239 * Unserializing instances of this class is forbidden.
240 *
241 * @since 1.7.4
242 */
243 public function __wakeup() {
244
245 _doing_it_wrong( __FUNCTION__, esc_html__( 'You should not do that!', 'customify' ), null );
246 }
247 }
248
249 // Handle various cache invalidations, in a proactive manner.
250 // We need to do the hooking here because by the time the class might be instantiated it might be too late.
251 add_action( 'customify_invalidate_all_caches', array( 'Customify_Design_Assets', 'invalidate_cache' ), 1 );
252
253 }
254