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 / class-customify-theme-configs.php

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

382 lines 11.8 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 * @return bool
104 * @since 1.7.4
105 *
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 * @param bool $skip_cache Optional. Whether to use the cached config or fetch a new one.
116 *
117 * @return array
118 * @since 1.7.4
119 *
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 * @param array $config This holds required keys for the plugin config like 'opt-name', 'panels', 'settings'
142 *
143 * @return array
144 * @since 1.7.4
145 *
146 */
147 public function maybe_activate_external_theme_config( $config ) {
148 // If somebody else already declared support for the Style Manager, we stop and let them have it.
149 if ( $this->is_supported() ) {
150 return $config;
151 }
152
153 // First gather details about the current (parent) theme.
154 $theme = wp_get_theme( get_template() );
155 // Bail if for some strange reason we couldn't find the theme.
156 if ( ! $theme->exists() ) {
157 return $config;
158 }
159
160 // Now determine if we have a theme config for the current theme.
161 $theme_configs = $this->get_theme_configs();
162
163 // We will go through every theme config and determine it's match score
164 foreach ( $theme_configs as $hashid => $theme_config ) {
165 // Loose matching means that the theme doesn't have to match all the conditions.
166 $loose_match = false;
167 if ( ! empty( $theme_config['loose_match'] ) ) {
168 $loose_match = true;
169 }
170
171 $matches = 0;
172 $total = 0;
173 if ( ! empty( $theme_config['name'] ) && $theme_config['name'] == $theme->get( 'Name' ) ) {
174 $matches ++;
175 $total ++;
176 }
177 if ( ! empty( $theme_config['slug'] ) && $theme_config['slug'] == $theme->get_stylesheet() ) {
178 $matches ++;
179 $total ++;
180 }
181 if ( ! empty( $theme_config['txtd'] ) && $theme_config['txtd'] == $theme->get( 'TextDomain' ) ) {
182 $matches ++;
183 $total ++;
184 }
185
186 $theme_configs[ $hashid ]['match_score'] = 0;
187 if ( true === $loose_match ) {
188 $theme_configs[ $hashid ]['match_score'] = $matches;
189 } elseif ( $matches === $total ) {
190 $theme_configs[ $hashid ]['match_score'] = $matches;
191 }
192 }
193
194 // Now we will order the theme configs by match scores, descending and get the highest matching candidate, if any.
195 $theme_configs = Customify_Array::array_orderby( $theme_configs, 'match_score', SORT_DESC );
196 $external_theme_config = array_shift( $theme_configs );
197 // If we've ended up with a theme config with a zero match score, bail.
198 if ( empty( $external_theme_config['match_score'] ) || empty( $external_theme_config['config']['sections'] ) ) {
199 return $config;
200 }
201
202 // Now we have a theme config to work with. Save it for later use.
203 $this->external_theme_config = $external_theme_config;
204
205 // Declare support for the Style Manager if there is such a section in the config
206 if ( isset( $external_theme_config['config']['sections']['style_manager_section'] ) ) {
207 add_theme_support( 'customizer_style_manager' );
208 }
209
210 return $config;
211 }
212
213 /**
214 * Maybe apply an external theme config.
215 *
216 * If the conditions are met, apply an external theme config. Right now we are only handling sections and their controls.
217 *
218 * @param array $config This holds required keys for the plugin config like 'opt-name', 'panels', 'settings'
219 *
220 * @return array
221 * @since 1.7.4
222 *
223 */
224 public function maybe_apply_external_theme_config( $config ) {
225 // Bail if we have no external theme config data.
226 if ( empty( $this->external_theme_config ) ) {
227 return $config;
228 }
229
230 // Apply the theme config.
231 // If we are dealing with the Customify default config, we need a clean slate, sort of.
232 if ( 'customify_defaults' === $config['opt-name'] ) {
233 // We will save the Style Manager config so we can merge with it. But the rest goes away.
234 $style_manager_section = array();
235 if ( isset( $config['sections']['style_manager_section'] ) ) {
236 $style_manager_section = $config['sections']['style_manager_section'];
237 }
238
239 $config['opt-name'] = get_template() . '_options';
240 if ( ! empty( $this->external_theme_config['config']['opt-name'] ) ) {
241 $config['opt-name'] = $this->external_theme_config['config']['opt-name'];
242 }
243
244 $config['sections'] = array(
245 'style_manager_section' => $style_manager_section,
246 );
247 }
248
249 // Now merge things.
250 $config['sections'] = Customify_Array::array_merge_recursive_distinct( $config['sections'], $this->external_theme_config['config']['sections'] );
251
252 return $config;
253 }
254
255 /**
256 * Maybe process certain "commands" from the external theme config.
257 *
258 * Mainly things like removing sections, controls, etc.
259 *
260 * @param WP_Customize_Manager $wp_customize
261 *
262 * @since 1.7.4
263 *
264 */
265 public function maybe_process_external_theme_config_extras( $wp_customize ) {
266 // Bail if we have no external theme config data.
267 if ( empty( $this->external_theme_config ) ) {
268 return;
269 }
270
271 // Maybe remove panels
272 if ( ! empty( $this->external_theme_config['config']['remove_panels'] ) ) {
273 // Standardize it.
274 if ( is_string( $this->external_theme_config['config']['remove_panels'] ) ) {
275 $this->external_theme_config['config']['remove_panels'] = array( $this->external_theme_config['config']['remove_panels'] );
276 }
277
278 foreach ( $this->external_theme_config['config']['remove_panels'] as $panel_id ) {
279 $wp_customize->remove_panel( $panel_id );
280 }
281 }
282
283 // Maybe remove sections
284 if ( ! empty( $this->external_theme_config['config']['remove_sections'] ) ) {
285 // Standardize it.
286 if ( is_string( $this->external_theme_config['config']['remove_sections'] ) ) {
287 $this->external_theme_config['config']['remove_sections'] = array( $this->external_theme_config['config']['remove_sections'] );
288 }
289
290 foreach ( $this->external_theme_config['config']['remove_sections'] as $section_id ) {
291
292 if ( 'widgets' === $section_id ) {
293 global $wp_registered_sidebars;
294
295 foreach ( $wp_registered_sidebars as $widget => $settings ) {
296 $wp_customize->remove_section( 'sidebar-widgets-' . $widget );
297 }
298 continue;
299 }
300
301 $wp_customize->remove_section( $section_id );
302 }
303 }
304
305 // Maybe remove settings
306 if ( ! empty( $this->external_theme_config['config']['remove_settings'] ) ) {
307 // Standardize it.
308 if ( is_string( $this->external_theme_config['config']['remove_settings'] ) ) {
309 $this->external_theme_config['config']['remove_settings'] = array( $this->external_theme_config['config']['remove_settings'] );
310 }
311
312 foreach ( $this->external_theme_config['config']['remove_settings'] as $setting_id ) {
313 $wp_customize->remove_setting( $setting_id );
314 }
315 }
316
317 // Maybe remove controls
318 if ( ! empty( $this->external_theme_config['config']['remove_controls'] ) ) {
319 // Standardize it.
320 if ( is_string( $this->external_theme_config['config']['remove_controls'] ) ) {
321 $this->external_theme_config['config']['remove_controls'] = array( $this->external_theme_config['config']['remove_controls'] );
322 }
323
324 foreach ( $this->external_theme_config['config']['remove_controls'] as $control_id ) {
325 $wp_customize->remove_control( $control_id );
326 }
327 }
328 }
329
330 /**
331 * Output the JSON in the Customizer page source.
332 */
333 public function maybe_output_json_external_config() {
334 if ( ! empty( $this->external_theme_config['config'] ) ) {
335 // Also output the JSON in a special hidden div for easy copy pasting.
336 // Also remove any multiple tabs.
337 echo "\n" . '<!--' . "\n" . 'Just copy&paste this:' . "\n" . "\n" . trim( str_replace( '\t\t', '', json_encode( $this->external_theme_config['config'] ) ) ) . "\n" . "\n" . '-->' . "\n";
338 }
339 }
340
341 /**
342 * Main Customify_Theme_Configs Instance
343 *
344 * Ensures only one instance of Customify_Theme_Configs is loaded or can be loaded.
345 *
346 * @return Customify_Theme_Configs Main Customify_Theme_Configs instance
347 * @since 1.7.4
348 * @static
349 *
350 */
351 public static function instance() {
352
353 if ( is_null( self::$_instance ) ) {
354 self::$_instance = new self();
355 }
356
357 return self::$_instance;
358 } // End instance ()
359
360 /**
361 * Cloning is forbidden.
362 *
363 * @since 1.7.4
364 */
365 public function __clone() {
366
367 _doing_it_wrong( __FUNCTION__, esc_html__( 'You should not do that!', 'customify' ), null );
368 }
369
370 /**
371 * Unserializing instances of this class is forbidden.
372 *
373 * @since 1.7.4
374 */
375 public function __wakeup() {
376
377 _doing_it_wrong( __FUNCTION__, esc_html__( 'You should not do that!', 'customify' ), null );
378 }
379 }
380
381 }
382