wp-customize-colors.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. require_once( __DIR__ . '/wp-customize-global-styles-setting.php' );
  3. require_once( __DIR__ . '/wp-customize-utils.php' );
  4. class GlobalStylesColorCustomizer {
  5. private $section_key = 'customize-global-styles-colors';
  6. private $user_color_palette;
  7. function __construct() {
  8. add_action( 'customize_register', array( $this, 'initialize' ) );
  9. add_action( 'customize_preview_init', array( $this, 'customize_preview_js' ) );
  10. add_action( 'customize_register', array( $this, 'create_customization_style_element' ) );
  11. add_action( 'customize_save_after', array( $this, 'handle_customize_save_after' ) );
  12. }
  13. function customize_preview_js() {
  14. wp_enqueue_script( 'customizer-preview-color', get_template_directory_uri() . '/inc/customizer/wp-customize-colors-preview.js', array( 'customize-preview' ) );
  15. wp_add_inline_script( 'customizer-preview-color', 'var userColorSectionKey="' . $this->section_key . '";', 'before' );
  16. wp_localize_script( 'customizer-preview-color', 'userColorPalette', $this->user_color_palette );
  17. }
  18. function update_user_color_palette( $wp_customize ) {
  19. foreach ( $this->user_color_palette as $key => $palette_item ) {
  20. $setting = $wp_customize->get_setting( $this->section_key . $palette_item['slug'] );
  21. if ( null !== $setting->post_value() ) {
  22. $this->user_color_palette[ $key ]['color'] = $setting->post_value();
  23. }
  24. }
  25. }
  26. function create_customization_style_element( $wp_customize ) {
  27. wp_enqueue_style( 'global-styles-colors-customizations', ' ', array( 'global-styles' ) ); // This needs to load after global_styles, hence the dependency
  28. $this->update_user_color_palette( $wp_customize );
  29. $css = ':root,body{';
  30. foreach ( $this->user_color_palette as $key => $palette_item ) {
  31. $setting = $wp_customize->get_setting( $this->section_key . $palette_item['slug'] );
  32. $css .= '--wp--preset--color--' . $palette_item['slug'] . ':' . $palette_item['color'] . ';';
  33. }
  34. $css .= '}';
  35. wp_add_inline_style( 'global-styles-colors-customizations', $css );
  36. }
  37. function initialize( $wp_customize ) {
  38. $this->user_color_palette = $this->build_user_color_palette();
  39. $this->register_color_controls( $wp_customize, $this->user_color_palette );
  40. }
  41. function build_user_color_palette() {
  42. // Get the merged theme.json.
  43. $theme_json = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data()->get_raw_data();
  44. $combined_color_palette = $theme_json['settings']['color']['palette']['theme'];
  45. $user_color_palette = null;
  46. if ( isset( $theme_json['settings']['color']['palette']['custom'] ) ) {
  47. $user_color_palette = $theme_json['settings']['color']['palette']['custom'];
  48. }
  49. // Combine theme settings with user settings.
  50. foreach ( $combined_color_palette as $key => $palette_item ) {
  51. //use user color value if there is one
  52. $user_color_value = $this->get_user_color_value( $palette_item['slug'], $user_color_palette );
  53. if ( isset( $user_color_value ) ) {
  54. $combined_color_palette[ $key ]['color'] = $user_color_value;
  55. }
  56. }
  57. return $combined_color_palette;
  58. }
  59. function get_user_color_value( $slug, $palette ) {
  60. if ( ! isset( $palette ) ) {
  61. return null;
  62. }
  63. foreach ( $palette as $palette_item ) {
  64. if ( $palette_item['slug'] === $slug ) {
  65. return $palette_item['color'];
  66. }
  67. }
  68. return null;
  69. }
  70. function register_color_controls( $wp_customize, $palette ) {
  71. $theme = wp_get_theme();
  72. //Add a Section to the Customizer for these bits
  73. $wp_customize->add_section(
  74. $this->section_key,
  75. array(
  76. 'capability' => 'edit_theme_options',
  77. 'description' => sprintf( __( 'Color Customization for %1$s', 'blockbase' ), $theme->name ),
  78. 'title' => __( 'Colors', 'blockbase' ),
  79. )
  80. );
  81. foreach ( $palette as $palette_item ) {
  82. $this->register_color_control( $wp_customize, $palette_item );
  83. }
  84. }
  85. function register_color_control( $wp_customize, $palette_item ) {
  86. $setting_key = $this->section_key . $palette_item['slug'];
  87. $global_styles_setting = new WP_Customize_Global_Styles_Setting(
  88. $wp_customize,
  89. $setting_key,
  90. array(
  91. 'user_value' => $palette_item['color'],
  92. )
  93. );
  94. $wp_customize->add_setting(
  95. $global_styles_setting,
  96. array(
  97. 'sanitize_callback' => 'sanitize_hex_color',
  98. )
  99. );
  100. $wp_customize->add_control(
  101. new WP_Customize_Color_Control(
  102. $wp_customize,
  103. $setting_key,
  104. array(
  105. 'section' => $this->section_key,
  106. 'label' => $palette_item['name'],
  107. )
  108. )
  109. );
  110. }
  111. function handle_customize_save_after( $wp_customize ) {
  112. //update the palette based on the controls
  113. $this->update_user_color_palette( $wp_customize );
  114. // Get the user's theme.json from the CPT.
  115. $user_custom_post_type_id = WP_Theme_JSON_Resolver_Gutenberg::get_user_global_styles_post_id();
  116. $global_styles_controller = new Gutenberg_REST_Global_Styles_Controller();
  117. $get_request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' );
  118. $get_request->set_param( 'id', $user_custom_post_type_id );
  119. $global_styles = $global_styles_controller->get_item( $get_request );
  120. // converts data to array (in some cases settings and styles are objects insted of arrays)
  121. $new_settings = (array) $global_styles->data['settings'];
  122. $new_styles = (array) $global_styles->data['styles'];
  123. // Set the new color settings
  124. $new_settings['color']['palette']['theme'] = $this->user_color_palette;
  125. // We used to set the values in 'custom' but moved to 'theme' to mirror GS functionality.
  126. // This ensures that new saves don't store the customizations in both places.
  127. if($new_settings['color']['palette']['custom']) {
  128. foreach ( $new_settings['color']['palette']['theme'] as $theme_color ) {
  129. foreach ( $new_settings['color']['palette']['custom'] as $key => $custom_color ) {
  130. if( $theme_color['slug'] === $custom_color['slug'] ) {
  131. unset( $new_settings['color']['palette']['custom'][$key] );
  132. }
  133. }
  134. }
  135. if ( ! $new_settings['color']['palette']['custom'] ) {
  136. unset ( $new_settings['color']['palette']['custom'] );
  137. }
  138. }
  139. // Add the updated global styles to the update request
  140. $update_request = new WP_REST_Request( 'PUT', '/wp/v2/global-styles/' );
  141. $update_request->set_param( 'id', $user_custom_post_type_id );
  142. $update_request->set_param( 'settings', $new_settings );
  143. $update_request->set_param( 'styles', $new_styles );
  144. // Update the theme.json with the new settings.
  145. $updated_global_styles = $global_styles_controller->update_item( $update_request );
  146. delete_transient( 'global_styles' );
  147. delete_transient( 'global_styles_' . get_stylesheet() );
  148. delete_transient( 'gutenberg_global_styles' );
  149. delete_transient( 'gutenberg_global_styles_' . get_stylesheet() );
  150. }
  151. }
  152. new GlobalStylesColorCustomizer;