wp-customize-colors.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <?php
  2. require_once 'wp-customize-global-styles-setting.php';
  3. require_once '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. if ( $this->theme_duotone_settings ) {
  18. wp_enqueue_script( 'colord', get_template_directory_uri() . '/inc/customizer/vendors/colord.min.js' );
  19. wp_localize_script( 'customizer-preview-color', 'userColorDuotone', $this->theme_duotone_settings );
  20. }
  21. }
  22. function update_user_color_palette( $wp_customize ) {
  23. foreach ( $this->user_color_palette as $key => $palette_item ) {
  24. $setting = $wp_customize->get_setting( $this->section_key . $palette_item['slug'] );
  25. if ( null !== $setting->post_value() ) {
  26. $this->user_color_palette[ $key ]['color'] = $setting->post_value();
  27. }
  28. }
  29. }
  30. function create_customization_style_element( $wp_customize ) {
  31. wp_enqueue_style( 'global-styles-colors-customizations', ' ', array( 'global-styles' ) ); // This needs to load after global_styles, hence the dependency
  32. $this->update_user_color_palette( $wp_customize );
  33. $css = ':root,body{';
  34. foreach ( $this->user_color_palette as $key => $palette_item ) {
  35. $setting = $wp_customize->get_setting( $this->section_key . $palette_item['slug'] );
  36. $css .= '--wp--preset--color--' . $palette_item['slug'] . ':' . $palette_item['color'] . ';';
  37. }
  38. $css .= '}';
  39. wp_add_inline_style( 'global-styles-colors-customizations', $css );
  40. }
  41. function initialize( $wp_customize ) {
  42. $this->user_color_palette = $this->build_user_color_palette();
  43. $this->theme_duotone_settings = $this->get_theme_duotone_settings();
  44. $this->register_color_controls( $wp_customize, $this->user_color_palette );
  45. }
  46. function get_theme_duotone_settings() {
  47. // Get the merged theme.json.
  48. $theme_json = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data()->get_raw_data();
  49. if ( array_key_exists( 'settings', $theme_json ) && array_key_exists( 'color', $theme_json['settings'] ) && array_key_exists( 'duotone', $theme_json['settings']['color'] ) && array_key_exists( 'theme', $theme_json['settings']['color']['duotone'] ) ) {
  50. return $theme_json['settings']['color']['duotone']['theme'];
  51. }
  52. return false;
  53. }
  54. function build_user_color_palette() {
  55. // Get the merged theme.json.
  56. $theme_json = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data()->get_raw_data();
  57. $combined_color_palette = $theme_json['settings']['color']['palette']['theme'];
  58. $user_color_palette = null;
  59. if ( isset( $theme_json['settings']['color']['palette']['user'] ) ) {
  60. $user_color_palette = $theme_json['settings']['color']['palette']['user'];
  61. }
  62. // Combine theme settings with user settings.
  63. foreach ( $combined_color_palette as $key => $palette_item ) {
  64. //make theme color value the default
  65. $combined_color_palette[ $key ]['default'] = $combined_color_palette[ $key ]['color'];
  66. //use user color value if there is one
  67. $user_color_value = $this->get_user_color_value( $palette_item['slug'], $user_color_palette );
  68. if ( isset( $user_color_value ) ) {
  69. $combined_color_palette[ $key ]['color'] = $user_color_value;
  70. }
  71. }
  72. return $combined_color_palette;
  73. }
  74. function get_user_color_value( $slug, $palette ) {
  75. if ( ! isset( $palette ) ) {
  76. return null;
  77. }
  78. foreach ( $palette as $palette_item ) {
  79. if ( $palette_item['slug'] === $slug ) {
  80. return $palette_item['color'];
  81. }
  82. }
  83. return null;
  84. }
  85. function register_color_controls( $wp_customize, $palette ) {
  86. $theme = wp_get_theme();
  87. //Add a Section to the Customizer for these bits
  88. $wp_customize->add_section(
  89. $this->section_key,
  90. array(
  91. 'capability' => 'edit_theme_options',
  92. 'description' => sprintf( __( 'Color Customization for %1$s', 'blockbase' ), $theme->name ),
  93. 'title' => __( 'Colors', 'blockbase' ),
  94. )
  95. );
  96. foreach ( $palette as $palette_item ) {
  97. $this->register_color_control( $wp_customize, $palette_item );
  98. }
  99. }
  100. function register_color_control( $wp_customize, $palette_item ) {
  101. $setting_key = $this->section_key . $palette_item['slug'];
  102. $global_styles_setting = new WP_Customize_Global_Styles_Setting(
  103. $wp_customize,
  104. $setting_key,
  105. array(
  106. 'default' => $palette_item['default'],
  107. 'user_value' => $palette_item['color'],
  108. )
  109. );
  110. $wp_customize->add_setting(
  111. $global_styles_setting,
  112. array(
  113. 'sanitize_callback' => 'sanitize_hex_color'
  114. )
  115. );
  116. $wp_customize->add_control(
  117. new WP_Customize_Color_Control(
  118. $wp_customize,
  119. $setting_key,
  120. array(
  121. 'section' => $this->section_key,
  122. 'label' => $palette_item['name'],
  123. )
  124. )
  125. );
  126. }
  127. function handle_customize_save_after( $wp_customize ) {
  128. //update the palette based on the controls
  129. $this->update_user_color_palette( $wp_customize );
  130. // Get the user's theme.json from the CPT.
  131. $user_custom_post_type_id = WP_Theme_JSON_Resolver_Gutenberg::get_user_custom_post_type_id();
  132. $user_theme_json_post = get_post( $user_custom_post_type_id );
  133. $user_theme_json_post_content = json_decode( $user_theme_json_post->post_content );
  134. // Set meta settings.
  135. $user_theme_json_post_content->version = 1;
  136. $user_theme_json_post_content->isGlobalStylesUserThemeJSON = true;
  137. // Only reset the palette if the setting exists, otherwise the whole settings array gets destroyed.
  138. if ( property_exists( $user_theme_json_post_content, 'settings' ) && property_exists( $user_theme_json_post_content->settings, 'color' ) && property_exists( $user_theme_json_post_content->settings->color, 'palette' ) ) {
  139. // Start with reset palette settings.
  140. unset( $user_theme_json_post_content->settings->color->palette );
  141. }
  142. //Set the color palette if it is !== the default
  143. if ( ! $this->check_if_colors_are_default() ) {
  144. $user_theme_json_post_content = set_settings_array(
  145. $user_theme_json_post_content,
  146. array( 'settings', 'color', 'palette' ),
  147. $this->user_color_palette
  148. );
  149. $primary_key = array_search('primary', array_column($this->user_color_palette, 'slug'));
  150. $background_key = array_search('background', array_column($this->user_color_palette, 'slug'));
  151. if ( $this->theme_duotone_settings && $primary_key !== null && $background_key !== null ) {
  152. $primary = $this->user_color_palette[$primary_key];
  153. $background = $this->user_color_palette[$background_key];
  154. //we invert the colors when the background is darker than the primary color
  155. if( colorLuminescence($primary['color']) > colorLuminescence($background['color']) ) {
  156. $primary = $this->user_color_palette[$background_key];
  157. $background = $this->user_color_palette[$primary_key];
  158. }
  159. $custom_duotone_filter = array(
  160. array(
  161. "colors" => array( $primary['color'], $background['color'] ),
  162. "slug" => "custom-filter",
  163. "name" => "Custom filter"
  164. )
  165. );
  166. $custom_duotone_filter_variable = "var(--wp--preset--duotone--custom-filter)";
  167. $user_theme_json_post_content = set_settings_array(
  168. $user_theme_json_post_content,
  169. array( 'settings', 'color', 'duotone' ),
  170. array_merge( $custom_duotone_filter, $this->theme_duotone_settings )
  171. );
  172. //replace the new filter in all blocks using duotone
  173. $theme_json = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data()->get_raw_data();
  174. if ( $theme_json['styles'] && $theme_json['styles']['blocks'] ) {
  175. foreach ( $theme_json['styles']['blocks'] as $key => $block ) {
  176. if( $block['filter'] ) {
  177. $user_theme_json_post_content = set_settings_array(
  178. $user_theme_json_post_content,
  179. array( 'styles', 'blocks', $key, 'filter', 'duotone' ),
  180. $custom_duotone_filter_variable
  181. );
  182. }
  183. }
  184. }
  185. }
  186. }
  187. // Update the theme.json with the new settings.
  188. $user_theme_json_post->post_content = json_encode( $user_theme_json_post_content );
  189. wp_update_post( $user_theme_json_post );
  190. delete_transient( 'global_styles' );
  191. delete_transient( 'gutenberg_global_styles' );
  192. delete_transient( 'gutenberg_global_styles_' . get_stylesheet() );
  193. }
  194. function check_if_colors_are_default() {
  195. foreach ( $this->user_color_palette as $palette_color ) {
  196. if ( strtoupper( $palette_color['color'] ) !== strtoupper( $palette_color['default'] ) ) {
  197. return false;
  198. }
  199. }
  200. return true;
  201. }
  202. }
  203. new GlobalStylesColorCustomizer;