PluginProbe
Customify / 2.0.2
Customify v2.0.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 / class-customify-theme-configs.php

class-customify-theme-configs.php in Customify 2.0.2, at includes/class-customify-theme-configs.php

379 lines 11.5 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 the theme configs.
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_Theme_Configs' ) ) :
15
16 class Customify_Theme_Configs {
17
18 /**
19 * Holds the only instance of this class.
20 * @var null|Customify_Theme_Configs
21 * @access protected
22 * @since 1.7.4
23 */
24 protected static $_instance = null;
25
26 /**
27 * The external theme config for the current active theme.
28 * @var array
29 * @access public
30 * @since 1.7.4
31 */
32 public $external_theme_config = null;
33
34 /**
35 * Constructor.
36 *
37 * @since 1.7.4
38 */
39 protected function __construct() {
40 $this->init();
41 }
42
43 /**
44 * Initialize this module.
45 *
46 * @since 1.7.4
47 */
48 public function init() {
49 // Hook up.
50 $this->add_hooks();
51 }
52
53 /**
54 * Initiate our hooks
55 *
56 * @since 1.7.4
57 */
58 public function add_hooks() {
59 /*
60 * Handle the external theme configuration logic. We use a late priority to be able to overwrite if we have to.
61 */
62 add_filter( 'customify_filter_fields', array( $this, 'maybe_activate_external_theme_config' ), 10, 1 );
63 add_filter( 'customify_filter_fields', array( $this, 'maybe_apply_external_theme_config' ), 100, 1 );
64 // Maybe the theme has instructed us to do things like removing sections or controls.
65 add_action( 'customize_register', array( $this, 'maybe_process_external_theme_config_extras' ), 11 );
66
67 /*
68 * Scripts enqueued in the Customizer.
69 */
70 add_action( 'customize_controls_init', array( $this, 'register_admin_customizer_scripts' ), 10 );
71 add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_admin_customizer_scripts' ), 10 );
72
73 /**
74 * Determine if we should output the theme root JSON in the Customizer for easier copy&paste to cloud.
75 */
76 if ( defined('CUSTOMIFY_SM_LOAD_THEME_ROOT_CONFIG') && true === CUSTOMIFY_SM_LOAD_THEME_ROOT_CONFIG ) {
77 add_filter( 'customize_controls_print_styles', array( $this, 'maybe_output_json_external_config' ), 0 );
78 }
79 }
80
81 /**
82 * Register Customizer admin scripts.
83 */
84 function register_admin_customizer_scripts() {
85
86 }
87
88 /**
89 * Enqueue Customizer admin scripts
90 */
91 function enqueue_admin_customizer_scripts() {
92 // If there is no style manager support, bail early.
93 if ( ! $this->is_supported() ) {
94 return;
95 }
96
97 // Enqueue the needed scripts, already registered.
98 }
99
100 /**
101 * Determine if Style Manager is supported.
102 *
103 * @since 1.7.4
104 *
105 * @return bool
106 */
107 public function is_supported() {
108 // For now we will only use the fact that Style Manager is supported.
109 return apply_filters( 'customify_theme_configs_are_supported', Customify_Style_Manager::instance()->is_supported() );
110 }
111
112 /**
113 * Get the themes configuration.
114 *
115 * @since 1.7.4
116 *
117 * @param bool $skip_cache Optional. Whether to use the cached config or fetch a new one.
118 *
119 * @return array
120 */
121 public function get_theme_configs( $skip_cache = false ) {
122 $theme_configs = array();
123
124 // Make sure that the Design Assets class is loaded.
125 require_once 'lib/class-customify-design-assets.php';
126
127 // Get the design assets data.
128 $design_assets = Customify_Design_Assets::instance()->get( $skip_cache );
129 if ( false !== $design_assets && ! empty( $design_assets['theme_configs'] ) ) {
130 $theme_configs = $design_assets['theme_configs'];
131 }
132
133 return apply_filters( 'customify_get_theme_configs', $theme_configs );
134 }
135
136 /**
137 * Maybe activate an external theme config.
138 *
139 * If the conditions are met, activate an external theme config by declaring support for the style manager and saving the config.
140 *
141 * @since 1.7.4
142 *
143 * @param array $config This holds required keys for the plugin config like 'opt-name', 'panels', 'settings'
144 * @return array
145 */
146 public function maybe_activate_external_theme_config( $config ) {
147 // If somebody else already declared support for the Style Manager, we stop and let them have it.
148 if ( $this->is_supported() ) {
149 return $config;
150 }
151
152 // First gather details about the current (parent) theme.
153 $theme = wp_get_theme( get_template() );
154 // Bail if for some strange reason we couldn't find the theme.
155 if ( ! $theme->exists() ) {
156 return $config;
157 }
158
159 // Now determine if we have a theme config for the current theme.
160 $theme_configs = $this->get_theme_configs();
161
162 // We will go through every theme config and determine it's match score
163 foreach ( $theme_configs as $hashid => $theme_config ) {
164 // Loose matching means that the theme doesn't have to match all the conditions.
165 $loose_match = false;
166 if ( ! empty( $theme_config['loose_match'] ) ) {
167 $loose_match = true;
168 }
169
170 $matches = 0;
171 $total = 0;
172 if ( ! empty( $theme_config['name'] ) && $theme_config['name'] == $theme->get('Name') ) {
173 $matches++;
174 $total++;
175 }
176 if ( ! empty( $theme_config['slug'] ) && $theme_config['slug'] == $theme->get_stylesheet() ) {
177 $matches++;
178 $total++;
179 }
180 if ( ! empty( $theme_config['txtd'] ) && $theme_config['txtd'] == $theme->get('TextDomain') ) {
181 $matches++;
182 $total++;
183 }
184
185 $theme_configs[ $hashid ]['match_score'] = 0;
186 if ( true === $loose_match ) {
187 $theme_configs[ $hashid ]['match_score'] = $matches;
188 } elseif( $matches === $total ) {
189 $theme_configs[ $hashid ]['match_score'] = $matches;
190 }
191 }
192
193 // Now we will order the theme configs by match scores, descending and get the highest matching candidate, if any.
194 $theme_configs = Customify_Array::array_orderby( $theme_configs, 'match_score', SORT_DESC );
195 $external_theme_config = array_shift( $theme_configs );
196 // If we've ended up with a theme config with a zero match score, bail.
197 if ( empty( $external_theme_config['match_score'] ) || empty( $external_theme_config['config']['sections'] ) ) {
198 return $config;
199 }
200
201 // Now we have a theme config to work with. Save it for later use.
202 $this->external_theme_config = $external_theme_config;
203
204 // Declare support for the Style Manager if there is such a section in the config
205 if ( isset( $external_theme_config['config']['sections']['style_manager_section'] ) ) {
206 add_theme_support( 'customizer_style_manager' );
207 }
208
209 return $config;
210 }
211
212 /**
213 * Maybe apply an external theme config.
214 *
215 * If the conditions are met, apply an external theme config. Right now we are only handling sections and their controls.
216 *
217 * @since 1.7.4
218 *
219 * @param array $config This holds required keys for the plugin config like 'opt-name', 'panels', 'settings'
220 * @return array
221 */
222 public function maybe_apply_external_theme_config( $config ) {
223 // Bail if we have no external theme config data.
224 if ( empty( $this->external_theme_config ) ) {
225 return $config;
226 }
227
228 // Apply the theme config.
229 // If we are dealing with the Customify default config, we need a clean slate, sort of.
230 if ( 'customify_defaults' === $config['opt-name'] ) {
231 // We will save the Style Manager config so we can merge with it. But the rest goes away.
232 $style_manager_section = array();
233 if ( isset( $config['sections']['style_manager_section'] ) ) {
234 $style_manager_section = $config['sections']['style_manager_section'];
235 }
236
237 $config['opt-name'] = get_template() . '_options';
238 if ( ! empty( $this->external_theme_config['config']['opt-name'] ) ) {
239 $config['opt-name'] = $this->external_theme_config['config']['opt-name'];
240 }
241
242 $config['sections'] = array(
243 'style_manager_section' => $style_manager_section,
244 );
245 }
246
247 // Now merge things.
248 $config['sections'] = Customify_Array::array_merge_recursive_distinct( $config['sections'],$this->external_theme_config['config']['sections'] );
249
250 return $config;
251 }
252
253 /**
254 * Maybe process certain "commands" from the external theme config.
255 *
256 * Mainly things like removing sections, controls, etc.
257 *
258 * @since 1.7.4
259 *
260 * @param WP_Customize_Manager $wp_customize
261 */
262 public function maybe_process_external_theme_config_extras( $wp_customize ) {
263 // Bail if we have no external theme config data.
264 if ( empty( $this->external_theme_config ) ) {
265 return;
266 }
267
268 // Maybe remove panels
269 if ( ! empty( $this->external_theme_config['config']['remove_panels'] ) ) {
270 // Standardize it.
271 if ( is_string( $this->external_theme_config['config']['remove_panels'] ) ) {
272 $this->external_theme_config['config']['remove_panels'] = array( $this->external_theme_config['config']['remove_panels'] );
273 }
274
275 foreach ( $this->external_theme_config['config']['remove_panels'] as $panel_id ) {
276 $wp_customize->remove_panel( $panel_id );
277 }
278 }
279
280 // Maybe remove sections
281 if ( ! empty( $this->external_theme_config['config']['remove_sections'] ) ) {
282 // Standardize it.
283 if ( is_string( $this->external_theme_config['config']['remove_sections'] ) ) {
284 $this->external_theme_config['config']['remove_sections'] = array( $this->external_theme_config['config']['remove_sections'] );
285 }
286
287 foreach ( $this->external_theme_config['config']['remove_sections'] as $section_id ) {
288
289 if ( 'widgets' === $section_id ) {
290 global $wp_registered_sidebars;
291
292 foreach ( $wp_registered_sidebars as $widget => $settings ) {
293 $wp_customize->remove_section( 'sidebar-widgets-' . $widget );
294 }
295 continue;
296 }
297
298 $wp_customize->remove_section( $section_id );
299 }
300 }
301
302 // Maybe remove settings
303 if ( ! empty( $this->external_theme_config['config']['remove_settings'] ) ) {
304 // Standardize it.
305 if ( is_string( $this->external_theme_config['config']['remove_settings'] ) ) {
306 $this->external_theme_config['config']['remove_settings'] = array( $this->external_theme_config['config']['remove_settings'] );
307 }
308
309 foreach ( $this->external_theme_config['config']['remove_settings'] as $setting_id ) {
310 $wp_customize->remove_setting( $setting_id );
311 }
312 }
313
314 // Maybe remove controls
315 if ( ! empty( $this->external_theme_config['config']['remove_controls'] ) ) {
316 // Standardize it.
317 if ( is_string( $this->external_theme_config['config']['remove_controls'] ) ) {
318 $this->external_theme_config['config']['remove_controls'] = array( $this->external_theme_config['config']['remove_controls'] );
319 }
320
321 foreach ( $this->external_theme_config['config']['remove_controls'] as $control_id ) {
322 $wp_customize->remove_control( $control_id );
323 }
324 }
325 }
326
327 /**
328 * Output the JSON in the Customizer page source.
329 */
330 public function maybe_output_json_external_config() {
331 if ( ! empty( $this->external_theme_config['config'] ) ) {
332 // Also output the JSON in a special hidden div for easy copy pasting.
333 // Also remove any multiple tabs.
334 echo PHP_EOL . '<!--' . PHP_EOL . 'Just copy&paste this:' . PHP_EOL . PHP_EOL . trim( str_replace( '\t\t', '', json_encode( $this->external_theme_config['config'] ) ) ) . PHP_EOL . PHP_EOL . '-->' . PHP_EOL;
335 }
336 }
337
338 /**
339 * Main Customify_Theme_Configs Instance
340 *
341 * Ensures only one instance of Customify_Theme_Configs is loaded or can be loaded.
342 *
343 * @since 1.7.4
344 * @static
345 *
346 * @return Customify_Theme_Configs Main Customify_Theme_Configs instance
347 */
348 public static function instance() {
349
350 if ( is_null( self::$_instance ) ) {
351 self::$_instance = new self();
352 }
353
354 return self::$_instance;
355 } // End instance ()
356
357 /**
358 * Cloning is forbidden.
359 *
360 * @since 1.7.4
361 */
362 public function __clone() {
363
364 _doing_it_wrong( __FUNCTION__,esc_html( __( 'Cheatin&#8217; huh?' ) ), null );
365 } // End __clone ()
366
367 /**
368 * Unserializing instances of this class is forbidden.
369 *
370 * @since 1.7.4
371 */
372 public function __wakeup() {
373
374 _doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin&#8217; huh?' ) ), null );
375 } // End __wakeup ()
376 }
377
378 endif;
379