Customizer.php (26366B)
1 <?php 2 3 namespace Materialis\Customizer; 4 5 use WP_Customize_Manager; 6 7 class Customizer 8 { 9 public $cpData = null; 10 11 /** @var \Materialis\Companion $_companion */ 12 private $_companion = null; 13 14 private $globalScriptsPrinted = false; 15 private $autoSetting = false; 16 17 private $registeredTypes 18 = array( 19 'panels' => array( 20 "Materialis\\Customizer\\BasePanel" => true, 21 ), 22 'sections' => array(), 23 'controls' => array( 24 "Materialis\\Customizer\\BaseControl" => true, 25 ), 26 ); 27 28 public function __construct($companion) 29 { 30 $this->_companion = $companion; 31 32 33 if ( ! $this->customizerSupportsViewedTheme()) { 34 return; 35 } 36 37 do_action('cloudpress\customizer\loaded'); 38 39 $this->register(array($this, '__registerComponents')); 40 41 $this->registerScripts(array($this, '__registerAssets'), 20); 42 $this->previewInit(array($this, '__registePreviewAssets')); 43 44 $this->register(array($this, '__addGlobalScript')); 45 $this->previewInit(array($this, '__previewScript')); 46 47 add_filter('customize_dynamic_setting_args', array($this, '__autoSettingsOptions'), PHP_INT_MAX, 2); 48 add_filter('customize_dynamic_setting_class', array($this, '__autoSettingsClass'), 10, 3); 49 50 add_filter('option_theme_mods_' . get_stylesheet(), array($this, 'addAutoSettingsInPreview')); 51 52 // require_once($this->_companion->assetsRootPath() . "/ajax_req/index.php"); 53 } 54 55 public function addAutoSettingsInPreview($values) 56 { 57 58 if (is_customize_preview()) { 59 global $wp_customize; 60 $settings = $wp_customize->unsanitized_post_values(); 61 62 foreach ($settings as $mod => $value) { 63 if (strpos($mod, "CP_AUTO_SETTING[") === 0) { 64 $key = str_replace("CP_AUTO_SETTING[", "", $mod); 65 $key = trim($key, "[]"); 66 $values[$key] = $value; 67 } 68 } 69 } 70 71 return $values; 72 73 } 74 75 public function customizerSupportsViewedTheme() 76 { 77 78 $supported = $this->companion()->isCurrentThemeSupported(); 79 $supported = apply_filters('cloudpress\customizer\supports', $supported); 80 81 return $supported; 82 83 } 84 85 public function companion() 86 { 87 return $this->_companion; 88 } 89 90 91 public function __registerComponents($wp_customize) 92 { 93 94 $this->cpData = apply_filters('cloudpress\customizer\data', $this->_companion->getCustomizerData(), $this); 95 $this->registerComponents($wp_customize); 96 } 97 98 public function __registerAssets($wp_customize) 99 { 100 $self = $this; 101 // add_action('customize_controls_enqueue_scripts', 102 // function () use ($self) { 103 wp_enqueue_style('thickbox'); 104 wp_enqueue_script('thickbox'); 105 106 $jsUrl = $self->companion()->assetsRootURL() . "/js/customizer/"; 107 $cssUrl = $self->companion()->assetsRootURL() . "/css"; 108 109 $ver = $self->companion()->version; 110 $textDomain = $self->companion()->getThemeSlug(); 111 112 113 // wp_enqueue_style('cp-fa-media-tab', $cssUrl . '/mdi-tab.css', array(), $ver); 114 wp_enqueue_style('cp-customizer-base', $cssUrl . '/customizer.css', array(), $ver); 115 wp_enqueue_style('cp-customizer-spectrum', $cssUrl . '/libs/spectrum.css', array(), $ver); 116 wp_enqueue_style($self->companion()->getThemeSlug() . '_material-icons', get_template_directory_uri() . '/assets/css/material-icons.css', array(), $ver); 117 118 if (apply_filters('\cloudpress\customizer\load_bundled_version', true)) { 119 wp_enqueue_script('customizer-base', $jsUrl . "customizer.bundle.min.js", array("{$textDomain}-customize"), $ver, true); 120 } else { 121 wp_enqueue_script('cp-customizer-spectrum', $jsUrl . "../libs/spectrum.js", array(), $ver, true); 122 wp_enqueue_script('cp-customizer-speakurl', $jsUrl . "../libs/speakingurl.js", array(), $ver, true); 123 wp_enqueue_script('cp-hooks-manager', $jsUrl . "../libs/hooks-manager.js", array(), $ver, true); 124 wp_enqueue_script('cp-customizer-base', $jsUrl . "customizer-base.js", array('cp-hooks-manager', 'cp-customizer-speakurl', "{$textDomain}-customize"), $ver, true); 125 wp_enqueue_script('cp-customizer-utils', $jsUrl . "customizer-utils.js", array('cp-customizer-base'), $ver, true); 126 wp_enqueue_script('cp-customizer-support', $jsUrl . "customizer-support.js", array(), $ver, true); 127 128 // wp_enqueue_script('cp-fa-media-tab', $jsUrl . '/mdi-tab.js', array('media-views'), $ver); 129 wp_enqueue_script('cp-webfonts', $jsUrl . '/web-fonts.js', array('jQuery')); 130 wp_enqueue_script('cp-customizer-shortcodes-popup', $jsUrl . "/customizer-shortcodes-popup.js", array('cp-customizer-base'), $ver, true); 131 wp_enqueue_script('cp-customizer-custom-popup', $jsUrl . "/customizer-custom-popup.js", array('cp-customizer-base'), $ver, true); 132 133 134 //wp_localize_script('cp-customizer-base', '__materialisCustomizerStrings', Translations::getTranslations()); 135 136 137 wp_register_script('customizer-base', null, array('cp-customizer-base', 'cp-customizer-utils', 'cp-customizer-support', 'cp-hooks-manager'), $ver, true); 138 wp_enqueue_script('customizer-base'); 139 140 wp_enqueue_script('customizer-custom-style-manager', 141 $jsUrl . "/customizer-custom-style-manager.js", array('customizer-base'), $ver, true); 142 wp_enqueue_script('customizer-section-settings-controls', 143 $jsUrl . "/customizer-section-settings-controls.js", array('customizer-base'), $ver, true); 144 145 wp_enqueue_script('customizer-current-page-settings', 146 $jsUrl . "/customizer-current-page-settings.js", array('customizer-base'), $ver, true); 147 148 wp_enqueue_script('customizer-section-settings-panel', 149 $jsUrl . "/customizer-section-settings-panel.js", array('customizer-section-settings-controls'), $ver, true); 150 151 wp_enqueue_script('customizer-features-popup', 152 $jsUrl . "/customizer-features-popup.js", array('customizer-base'), $ver, true); 153 154 wp_enqueue_script('customizer-page-settings-panel', 155 $jsUrl . "/customizer-page-settings-panel.js", array('customizer-base'), $ver, true); 156 } 157 158 159 wp_localize_script('customizer-base', '__materialisCustomizerStrings', Translations::getTranslations()); 160 do_action('cloudpress\customizer\add_assets', $self, $jsUrl, $cssUrl); 161 // }); 162 } 163 164 public function __addGlobalScript($wp_customize) 165 { 166 $self = $this; 167 168 169 add_action('customize_controls_print_scripts', function () { 170 if (isset($_REQUEST['cp__changeset__preview'])): ?> 171 <style> 172 #customize-controls { 173 display: none !important; 174 } 175 176 div#customize-preview { 177 position: fixed; 178 top: 0px; 179 left: 0px; 180 height: 100%; 181 width: 100%; 182 z-index: 10000000; 183 display: block; 184 } 185 186 html, body { 187 width: 100%; 188 max-width: 100%; 189 overflow-x: hidden; 190 } 191 </style> 192 <script> 193 window.__isCPChangesetPreview = true; 194 </script> 195 <?php endif; 196 }); 197 198 add_action('customize_controls_print_footer_scripts', function () use ($self) { 199 200 if (defined("CP__addGlobalScript")) { 201 return; 202 } 203 204 define("CP__addGlobalScript", "1"); 205 206 $isScriptDebugging = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG); 207 $isShowingNextFeaturesActive = (defined('SHOW_NEXT_FEATURES') && SHOW_NEXT_FEATURES); 208 209 $featuresPopups = apply_filters('cloudpress\customizer\feature_popups', array()); 210 $featuresPopup = null; 211 foreach ($featuresPopups as $key => $data) { 212 $disabled = get_option("feature_popup_{$data['id']}_disabled", false); 213 if ( ! intval($disabled)) { 214 $featuresPopup = $data; 215 $featuresPopup['nonce'] = wp_create_nonce("companion_disable_popup"); 216 } 217 } 218 219 $globalData = apply_filters('cloudpress\customizer\global_data', array( 220 "version" => $self->companion()->getCustomizerData('version'), 221 "data" => $self->companion()->getCustomizerData('data'), 222 "slugPrefix" => $self->companion()->getThemeSlug(true), 223 "cssAllowedProperties" => \Materialis\Utils\Utils::getAllowCssProperties(), 224 "stylesheetURL" => get_stylesheet_directory_uri(), 225 "includesURL" => includes_url(), 226 "themeURL" => get_template_directory_uri(), 227 "isMultipage" => $self->companion()->isMultipage(), 228 "restURL" => get_rest_url(), 229 "SCRIPT_DEBUG" => $isScriptDebugging, 230 "SHOW_NEXT_FEATURES" => $isShowingNextFeaturesActive, 231 "isWoocommerceInstalled" => class_exists('WooCommerce'), 232 "featuresPopup" => $featuresPopup, 233 )); 234 ?> 235 <!-- CloudPress Companion Global Data START --> 236 <script type="text/javascript"> 237 (function () { 238 parent.cpCustomizerGlobal = window.cpCustomizerGlobal = { 239 pluginOptions: <?php echo json_encode($globalData); ?> 240 }; 241 })(); 242 </script> 243 244 <div id="cp-full-screen-loader" class="active"> 245 <div class="wrapper"> 246 <div id="floatingCirclesG"> 247 <div class="f_circleG" id="frotateG_01"></div> 248 <div class="f_circleG" id="frotateG_02"></div> 249 <div class="f_circleG" id="frotateG_03"></div> 250 <div class="f_circleG" id="frotateG_04"></div> 251 <div class="f_circleG" id="frotateG_05"></div> 252 <div class="f_circleG" id="frotateG_06"></div> 253 <div class="f_circleG" id="frotateG_07"></div> 254 <div class="f_circleG" id="frotateG_08"></div> 255 </div> 256 <p class="message-area"><?php _e('Please wait,<br/>this might take a little while', 'one-page-express-pro') ?></p> 257 </div> 258 </div> 259 260 <?php $frontpageCB = uniqid('cb_') . "_CreateFrontendPage"; ?> 261 <div class='reiki-needed-container' data-type="select"> 262 <div class="description customize-section-description"> 263 <span><?php _e('This section only works when the ' . $self->companion()->themeName . ' custom front page is open in Customizer', 'cloudpress-companion'); ?>.</span> 264 <a onclick="<?php echo $frontpageCB ?>()" class="reiki-needed select available-item-hover-button"><?php _e('Open ' . $self->companion()->themeName . ' Front Page', 'reiki-companion'); ?></a> 265 </div> 266 </div> 267 <script> 268 <?php echo $frontpageCB ?> = function () { 269 jQuery.post( 270 parent.ajaxurl, 271 { 272 action: 'create_home_page', 273 create_home_page_nounce: '<?php echo wp_create_nonce('create_home_page_nounce'); ?>' 274 }, 275 function (response) { 276 parent.window.location = (parent.window.location + "").split("?")[0]; 277 } 278 ); 279 } 280 </script> 281 282 <div class='reiki-needed-container' data-type="activate"> 283 <div class="description customize-section-description"> 284 <span><?php _e('This section only works when the ' . $self->companion()->themeName . ' custom front page is activated', 'cloudpress-companion'); ?>.</span> 285 <a onclick="<?php echo $frontpageCB ?>()" class="reiki-needed activate available-item-hover-button"><?php _e('Activate ' . $self->companion()->themeName . ' Front Page', 'cloudpress-companion'); ?></a> 286 </div> 287 </div> 288 289 <?php $makeMaintainable = uniqid('cb_') . "_MakePageMaintainable"; ?> 290 291 <script> 292 var <?php echo $makeMaintainable ?> = 293 294 function () { 295 var page = top.CP_Customizer.preview.data().pageID; 296 jQuery.post(ajaxurl, { 297 action: 'cp_open_in_customizer', 298 page: page, 299 mark_as_editable: true 300 }).done(function (response) { 301 window.location = response.trim(); 302 }); 303 } 304 </script> 305 306 <div class='reiki-needed-container' data-type="edit-this-page"> 307 <div class="description customize-section-description"> 308 <span><?php _e('This page is not marked as editable in Customizer', 'cloudpress-companion'); ?>.</span> 309 <a onclick="<?php echo $makeMaintainable ?>()" class="reiki-needed edit-this-page available-item-hover-button"><?php _e('Make this page editable in customizer', 'cloudpress-companion'); ?></a> 310 <span style="font-size: 11px; padding-top: 14px;line-height: 1.2;"><?php _e('A page revision will be created so you can go back if the button was pressed by mistake', 'cloudpress-companion'); ?>.</span> 311 </div> 312 </div> 313 314 315 <div class='reiki-needed-container' data-type="edit-this-product"> 316 <div class="description customize-section-description"> 317 <span><?php _e('This product page is not marked as editable in Customizer', 'cloudpress-companion'); ?>.</span> 318 <a onclick="<?php echo $makeMaintainable ?>()" class="reiki-needed edit-this-page available-item-hover-button"><?php _e('Make this product editable in customizer', 'cloudpress-companion'); ?></a> 319 <span style="font-size: 11px; padding-top: 14px;line-height: 1.2;"><?php _e('A page revision will be created so you can go back if the button was pressed by mistake', 'cloudpress-companion'); ?>.</span> 320 </div> 321 </div> 322 323 324 <?php do_action("cloudpress\customizer\global_scripts", $self); ?> 325 <!-- CloudPress Companion Global Data END --> 326 <?php 327 328 }); 329 } 330 331 public function __registePreviewAssets($wp_customize) 332 { 333 $jsUrl = $this->_companion->assetsRootURL() . "/js/customizer"; 334 $cssUrl = $this->_companion->assetsRootURL() . "/css"; 335 336 wp_enqueue_style('cp-customizer-spectrum', $cssUrl . '/libs/spectrum.css'); 337 wp_enqueue_style('cp-customizer-preview', $cssUrl . '/preview.css'); 338 wp_enqueue_style('cp-customizer-preview-tinymce', $cssUrl . '/tinymce.css'); 339 340 wp_enqueue_script('cp-customizer-preview', $jsUrl . "/preview.js", array('jquery', 'jquery-ui-sortable', 'customize-preview')); 341 } 342 343 public function __autoSettingsOptions($args, $setting) 344 { 345 $settingRegex = \Materialis\Customizer\Settings\AutoSetting::SETTING_PATTERN; 346 347 if (preg_match($settingRegex, $setting)) { 348 $args = array( 349 'transport' => 'postMessage', 350 'type' => \Materialis\Customizer\Settings\AutoSetting::TYPE, 351 ); 352 } 353 354 return $args; 355 } 356 357 358 public function __autoSettingsClass($class, $setting, $args) 359 { 360 $settingRegex = \Materialis\Customizer\Settings\AutoSetting::SETTING_PATTERN; 361 362 if (preg_match($settingRegex, $setting)) { 363 $class = "\\Materialis\\Customizer\\Settings\\AutoSetting"; 364 } 365 366 return $class; 367 } 368 369 public function queryVarsCleaner($input) 370 { 371 foreach ($input as $key => &$value) { 372 if (is_array($value)) { 373 $value = $this->queryVarsCleaner($value); 374 } else { 375 if (strpos($key, 'cache') !== false) { 376 unset($input[$key]); 377 } 378 } 379 } 380 381 return array_filter($input); 382 } 383 384 public function __previewScript($wp_customize) 385 { 386 if (defined("CP__previewScript")) { 387 return; 388 } 389 390 define("CP__previewScript", "1"); 391 392 $self = $this; 393 394 add_action('wp_footer', function () use ($self) { 395 global $wp_query, $post; 396 397 $vars = $self->queryVarsCleaner($wp_query->query_vars); 398 $vars['post_type'] = get_post_type(); 399 400 $previewData = apply_filters('cloudpress\customizer\preview_data', array( 401 "version" => $self->companion()->getCustomizerData('version'), 402 "slug" => $self->companion()->getThemeSlug(), 403 "maintainable" => $self->companion()->isMaintainable(), 404 "isFrontPage" => $self->companion()->isFrontPage(), 405 "canEditInCustomizer" => $self->companion()->canEditInCustomizer(), 406 "pageID" => $self->companion()->getCurrentPageId(), 407 "queryVars" => $vars, 408 "hasFrontPage" => ($self->companion()->getFrontPage() !== null), 409 "siteURL" => get_home_url(), 410 "pageURL" => $post ? get_page_link() : null, 411 "includesURL" => includes_url(), 412 "mod_defaults" => apply_filters('cloudpress\customizer\mod_defaults', array()), 413 "isWoocommerceInstalled" => class_exists('WooCommerce'), 414 )); 415 ?> 416 <!-- CloudPress Companion Preview Data START --> 417 <script type="text/javascript"> 418 (function () { 419 window.cpCustomizerPreview = <?php echo json_encode($previewData); ?>; 420 wp.customize.bind('preview-ready', function () { 421 jQuery(function () { 422 423 setTimeout(function () { 424 parent.postMessage('cloudpress_update_customizer', "*"); 425 }, 100); 426 427 }); 428 429 }); 430 })(); 431 </script> 432 433 <style> 434 *[contenteditable="true"] { 435 user-select: auto !important; 436 -webkit-user-select: auto !important; 437 -moz-user-select: text !important; 438 } 439 </style> 440 441 <?php do_action("cloudpress\customizer\preview_scripts", $self); ?> 442 <!-- CloudPress Companion Preview Data END --> 443 <?php 444 445 }); 446 } 447 448 public function removeNamespace($name) 449 { 450 $parts = explode("\\", $name); 451 $result = array(); 452 453 foreach ($parts as $part) { 454 $part = trim($part); 455 if ( ! empty($part)) { 456 $result[] = $part; 457 } 458 } 459 460 $result = implode("-", $result); 461 462 return strtolower($result); 463 } 464 465 private function registerComponents($wp_customize) 466 { 467 $wp_customize->register_panel_type("Materialis\\Customizer\\BasePanel"); 468 $wp_customize->register_control_type("Materialis\\Customizer\\BaseControl"); 469 470 foreach ($this->cpData['customizer'] as $category => $components) { 471 switch ($category) { 472 case 'panels': 473 $this->registerPanels($wp_customize, $components); 474 break; 475 case 'sections': 476 $components = $this->cpData['customizer']['sections']; 477 $this->registerSections($wp_customize, $components); 478 break; 479 480 case 'controls': 481 $components = $this->cpData['customizer']['controls']; 482 $this->registerControls($wp_customize, $components); 483 break; 484 case 'settings': 485 $components = $this->cpData['customizer']['settings']; 486 $this->registerSettings($wp_customize, $components); 487 break; 488 } 489 } 490 } 491 492 public function registerPanels($wp_customize, $components) 493 { 494 foreach ($components as $id => $data) { 495 if ($panel = $wp_customize->get_panel($id)) { 496 if (isset($data['wp_data'])) { 497 foreach ($data['wp_data'] as $key => $value) { 498 $panel->$key = $value; 499 } 500 } 501 continue; 502 } 503 504 505 $panelClass = "Materialis\\Customizer\\BasePanel"; 506 507 if (isset($data['class']) && $data['class']) { 508 $panelClass = $data['class']; 509 } 510 511 if ( ! isset($this->registeredTypes['panels'][$panelClass])) { 512 $this->registeredTypes['panels'][$panelClass] = true; 513 } 514 515 516 if (strpos($panelClass, "WP_Customize_") !== false) { 517 $data = isset($data['wp_data']) ? $data['wp_data'] : array(); 518 } 519 520 $wp_customize->add_panel(new $panelClass($wp_customize, $id, $data)); 521 } 522 } 523 524 525 public function registerSections($wp_customize, $components) 526 { 527 foreach ($components as $id => $data) { 528 if ($section = $wp_customize->get_section($id)) { 529 if (isset($data['wp_data'])) { 530 foreach ($data['wp_data'] as $key => $value) { 531 $section->$key = $value; 532 } 533 } 534 continue; 535 } 536 537 $sectionClass = "Materialis\\Customizer\\BaseSection"; 538 539 if (isset($data['class']) && $data['class']) { 540 $sectionClass = $data['class']; 541 } 542 543 if ( ! isset($this->registeredTypes['sections'][$sectionClass])) { 544 $this->registeredTypes['sections'][$sectionClass] = true; 545 $wp_customize->register_section_type($sectionClass); 546 } 547 548 549 if (strpos($sectionClass, "WP_Customize_") !== false) { 550 $data = isset($data['wp_data']) ? $data['wp_data'] : array(); 551 } 552 553 $wp_customize->add_section(new $sectionClass($wp_customize, $id, $data)); 554 } 555 } 556 557 public function registerControls($wp_customize, $components) 558 { 559 foreach ($components as $id => $data) { 560 if ($control = $wp_customize->get_control($id)) { 561 if (isset($data['wp_data'])) { 562 foreach ($data['wp_data'] as $key => $value) { 563 $control->$key = $value; 564 } 565 } 566 continue; 567 } 568 569 $controlClass = "Materialis\\Customizer\\BaseControl"; 570 if (isset($data['class']) && $data['class']) { 571 $controlClass = $data['class']; 572 } 573 574 if ( ! isset($this->registeredTypes['controls'][$controlClass])) { 575 $this->registeredTypes['controls'][$controlClass] = true; 576 // $wp_customize->register_control_type($controlClass); 577 } 578 579 580 if (strpos($controlClass, "WP_Customize_") !== false) { 581 $data = isset($data['wp_data']) ? $data['wp_data'] : array(); 582 } 583 584 if (strpos($controlClass, "kirki:") === 0) { 585 $data = isset($data['wp_data']) ? $data['wp_data'] : array(); 586 $data['type'] = str_replace("kirki:", "", $controlClass); 587 \Kirki::add_field($id, $data); 588 } else { 589 $wp_customize->add_control(new $controlClass($wp_customize, $id, $data)); 590 } 591 } 592 } 593 594 public function registerSettings($wp_customize, $components) 595 { 596 foreach ($components as $id => $data) { 597 if ($setting = $wp_customize->get_setting($id)) { 598 if (isset($data['wp_data'])) { 599 foreach ($data['wp_data'] as $key => $value) { 600 if ($key === "default") { 601 $value = BaseSetting::filterDefault($value); 602 } 603 $setting->$key = $value; 604 } 605 } 606 continue; 607 } 608 609 $settingClass = "Materialis\\Customizer\\BaseSetting"; 610 611 if (isset($data['class']) && $data['class']) { 612 $settingClass = $data['class']; 613 } 614 615 if (strpos($settingClass, "WP_Customize_") !== false) { 616 $data = isset($data['wp_data']) ? $data['wp_data'] : array(); 617 } 618 619 620 if (strpos($settingClass, "kirki") === 0) { 621 $settingClass = "Materialis\\Customizer\\BaseSetting"; 622 $data['__is__kirki'] = true; 623 } 624 625 626 $setting = new $settingClass($wp_customize, $id, $data); 627 628 if ( ! $setting->isKirki()) { 629 $wp_customize->add_setting($setting); 630 } 631 632 if (method_exists($setting, 'setControl')) { 633 $setting->setControl(); 634 } 635 } 636 } 637 638 public function register($callback, $priority = 40) 639 { 640 add_action('customize_register', $callback, $priority); 641 } 642 643 public function registerScripts($callback, $priority = 40) 644 { 645 add_action('customize_controls_enqueue_scripts', $callback, $priority); 646 } 647 648 public function previewInit($callback, $priority = 40) 649 { 650 add_action('customize_preview_init', $callback, $priority); 651 } 652 }