@@ -19,134 +19,134 @@ |
||
19 | 19 | */ |
20 | 20 | class Upload extends Field { |
21 | 21 | |
22 | - /** |
|
23 | - * The field type. |
|
24 | - * |
|
25 | - * @access public |
|
26 | - * @since 1.0 |
|
27 | - * @var string |
|
28 | - */ |
|
29 | - public $type = 'kirki-upload'; |
|
30 | - |
|
31 | - /** |
|
32 | - * The control class-name. |
|
33 | - * |
|
34 | - * @access protected |
|
35 | - * @since 0.1 |
|
36 | - * @var string |
|
37 | - */ |
|
38 | - protected $control_class = '\Kirki\Control\Upload'; |
|
39 | - |
|
40 | - /** |
|
41 | - * Filter arguments before creating the setting. |
|
42 | - * |
|
43 | - * @access public |
|
44 | - * @since 0.1 |
|
45 | - * @param array $args The field arguments. |
|
46 | - * @param WP_Customize_Manager $wp_customize The customizer instance. |
|
47 | - * @return array |
|
48 | - */ |
|
49 | - public function filter_setting_args( $args, $wp_customize ) { |
|
50 | - if ( $args['settings'] === $this->args['settings'] ) { |
|
51 | - $args = parent::filter_setting_args( $args, $wp_customize ); |
|
52 | - |
|
53 | - // Set the sanitize-callback if none is defined. |
|
54 | - if ( ! isset( $args['sanitize_callback'] ) || ! $args['sanitize_callback'] ) { |
|
55 | - |
|
56 | - $args['sanitize_callback'] = function( $value ) { |
|
57 | - $save_as = isset( $this->args['choices']['save_as'] ) ? $this->args['choices']['save_as'] : 'url'; |
|
58 | - |
|
59 | - return self::sanitize( $value, $save_as ); |
|
60 | - }; |
|
61 | - |
|
62 | - } |
|
63 | - } |
|
64 | - |
|
65 | - return $args; |
|
66 | - } |
|
67 | - |
|
68 | - /** |
|
69 | - * Filter arguments before creating the control. |
|
70 | - * |
|
71 | - * @access public |
|
72 | - * @since 0.1 |
|
73 | - * @param array $args The field arguments. |
|
74 | - * @param WP_Customize_Manager $wp_customize The customizer instance. |
|
75 | - * @return array |
|
76 | - */ |
|
77 | - public function filter_control_args( $args, $wp_customize ) { |
|
78 | - if ( $args['settings'] === $this->args['settings'] ) { |
|
79 | - $args = parent::filter_control_args( $args, $wp_customize ); |
|
80 | - $args['type'] = 'upload'; |
|
81 | - } |
|
82 | - return $args; |
|
83 | - } |
|
84 | - |
|
85 | - /** |
|
86 | - * Sanitizes the field value. |
|
87 | - * |
|
88 | - * @since 1.0.2 |
|
89 | - * |
|
90 | - * @param mixed $value The field value. |
|
91 | - * @param string $save_as The expected saving format. |
|
92 | - * |
|
93 | - * @return mixed |
|
94 | - */ |
|
95 | - public static function sanitize( $value, $save_as = 'url' ) { |
|
96 | - |
|
97 | - if ( 'array' === $save_as ) { |
|
98 | - |
|
99 | - if ( is_array( $value ) ) { |
|
100 | - return [ |
|
101 | - 'id' => ( isset( $value['id'] ) && '' !== $value['id'] ) ? (int) $value['id'] : '', |
|
102 | - 'url' => ( isset( $value['url'] ) && '' !== $value['url'] ) ? esc_url_raw( $value['url'] ) : '', |
|
103 | - 'filename' => ( isset( $value['filename'] ) && '' !== $value['filename'] ) ? sanitize_text_field( $value['filename'] ) : '', |
|
104 | - ]; |
|
105 | - } elseif ( is_string( $value ) && ! is_numeric( $value ) ) { |
|
106 | - // Here, we assume that the value is the URL. |
|
107 | - $attachment_id = attachment_url_to_postid( $value ); |
|
108 | - |
|
109 | - return [ |
|
110 | - 'id' => $attachment_id, |
|
111 | - 'url' => $value, |
|
112 | - 'filename' => basename( get_attached_file( $attachment_id ) ), |
|
113 | - ]; |
|
114 | - } else { |
|
115 | - // Here, we assume that the value is int or numeric (the attachment ID). |
|
116 | - $value = absint( $value ); |
|
117 | - |
|
118 | - return [ |
|
119 | - 'id' => $value, |
|
120 | - 'url' => wp_get_attachment_url( $value ), |
|
121 | - 'filename' => basename( get_attached_file( $value ) ), |
|
122 | - ]; |
|
123 | - } |
|
124 | - } elseif ( 'id' === $save_as ) { |
|
125 | - |
|
126 | - if ( is_string( $value ) && ! is_numeric( $value ) ) { |
|
127 | - // Here, we assume that the value is the URL. |
|
128 | - return attachment_url_to_postid( $value ); |
|
129 | - } elseif ( is_array( $value ) && isset( $value['id'] ) ) { |
|
130 | - return absint( $value['id'] ); |
|
131 | - } |
|
132 | - |
|
133 | - // Here, we assume that the value is int or numeric (the attachment ID). |
|
134 | - return absint( $value ); |
|
135 | - |
|
136 | - } |
|
137 | - |
|
138 | - // If we're reaching this point, then we're saving the URL. |
|
139 | - if ( is_array( $value ) && isset( $value['url'] ) ) { |
|
140 | - $value = $value['url']; |
|
141 | - } elseif ( is_numeric( $value ) ) { |
|
142 | - $value = absint( $value ); |
|
143 | - $value = wp_get_attachment_url( $value ); |
|
144 | - } else { |
|
145 | - $value = esc_url_raw( $value ); |
|
146 | - } |
|
147 | - |
|
148 | - return $value; |
|
149 | - |
|
150 | - } |
|
22 | + /** |
|
23 | + * The field type. |
|
24 | + * |
|
25 | + * @access public |
|
26 | + * @since 1.0 |
|
27 | + * @var string |
|
28 | + */ |
|
29 | + public $type = 'kirki-upload'; |
|
30 | + |
|
31 | + /** |
|
32 | + * The control class-name. |
|
33 | + * |
|
34 | + * @access protected |
|
35 | + * @since 0.1 |
|
36 | + * @var string |
|
37 | + */ |
|
38 | + protected $control_class = '\Kirki\Control\Upload'; |
|
39 | + |
|
40 | + /** |
|
41 | + * Filter arguments before creating the setting. |
|
42 | + * |
|
43 | + * @access public |
|
44 | + * @since 0.1 |
|
45 | + * @param array $args The field arguments. |
|
46 | + * @param WP_Customize_Manager $wp_customize The customizer instance. |
|
47 | + * @return array |
|
48 | + */ |
|
49 | + public function filter_setting_args( $args, $wp_customize ) { |
|
50 | + if ( $args['settings'] === $this->args['settings'] ) { |
|
51 | + $args = parent::filter_setting_args( $args, $wp_customize ); |
|
52 | + |
|
53 | + // Set the sanitize-callback if none is defined. |
|
54 | + if ( ! isset( $args['sanitize_callback'] ) || ! $args['sanitize_callback'] ) { |
|
55 | + |
|
56 | + $args['sanitize_callback'] = function( $value ) { |
|
57 | + $save_as = isset( $this->args['choices']['save_as'] ) ? $this->args['choices']['save_as'] : 'url'; |
|
58 | + |
|
59 | + return self::sanitize( $value, $save_as ); |
|
60 | + }; |
|
61 | + |
|
62 | + } |
|
63 | + } |
|
64 | + |
|
65 | + return $args; |
|
66 | + } |
|
67 | + |
|
68 | + /** |
|
69 | + * Filter arguments before creating the control. |
|
70 | + * |
|
71 | + * @access public |
|
72 | + * @since 0.1 |
|
73 | + * @param array $args The field arguments. |
|
74 | + * @param WP_Customize_Manager $wp_customize The customizer instance. |
|
75 | + * @return array |
|
76 | + */ |
|
77 | + public function filter_control_args( $args, $wp_customize ) { |
|
78 | + if ( $args['settings'] === $this->args['settings'] ) { |
|
79 | + $args = parent::filter_control_args( $args, $wp_customize ); |
|
80 | + $args['type'] = 'upload'; |
|
81 | + } |
|
82 | + return $args; |
|
83 | + } |
|
84 | + |
|
85 | + /** |
|
86 | + * Sanitizes the field value. |
|
87 | + * |
|
88 | + * @since 1.0.2 |
|
89 | + * |
|
90 | + * @param mixed $value The field value. |
|
91 | + * @param string $save_as The expected saving format. |
|
92 | + * |
|
93 | + * @return mixed |
|
94 | + */ |
|
95 | + public static function sanitize( $value, $save_as = 'url' ) { |
|
96 | + |
|
97 | + if ( 'array' === $save_as ) { |
|
98 | + |
|
99 | + if ( is_array( $value ) ) { |
|
100 | + return [ |
|
101 | + 'id' => ( isset( $value['id'] ) && '' !== $value['id'] ) ? (int) $value['id'] : '', |
|
102 | + 'url' => ( isset( $value['url'] ) && '' !== $value['url'] ) ? esc_url_raw( $value['url'] ) : '', |
|
103 | + 'filename' => ( isset( $value['filename'] ) && '' !== $value['filename'] ) ? sanitize_text_field( $value['filename'] ) : '', |
|
104 | + ]; |
|
105 | + } elseif ( is_string( $value ) && ! is_numeric( $value ) ) { |
|
106 | + // Here, we assume that the value is the URL. |
|
107 | + $attachment_id = attachment_url_to_postid( $value ); |
|
108 | + |
|
109 | + return [ |
|
110 | + 'id' => $attachment_id, |
|
111 | + 'url' => $value, |
|
112 | + 'filename' => basename( get_attached_file( $attachment_id ) ), |
|
113 | + ]; |
|
114 | + } else { |
|
115 | + // Here, we assume that the value is int or numeric (the attachment ID). |
|
116 | + $value = absint( $value ); |
|
117 | + |
|
118 | + return [ |
|
119 | + 'id' => $value, |
|
120 | + 'url' => wp_get_attachment_url( $value ), |
|
121 | + 'filename' => basename( get_attached_file( $value ) ), |
|
122 | + ]; |
|
123 | + } |
|
124 | + } elseif ( 'id' === $save_as ) { |
|
125 | + |
|
126 | + if ( is_string( $value ) && ! is_numeric( $value ) ) { |
|
127 | + // Here, we assume that the value is the URL. |
|
128 | + return attachment_url_to_postid( $value ); |
|
129 | + } elseif ( is_array( $value ) && isset( $value['id'] ) ) { |
|
130 | + return absint( $value['id'] ); |
|
131 | + } |
|
132 | + |
|
133 | + // Here, we assume that the value is int or numeric (the attachment ID). |
|
134 | + return absint( $value ); |
|
135 | + |
|
136 | + } |
|
137 | + |
|
138 | + // If we're reaching this point, then we're saving the URL. |
|
139 | + if ( is_array( $value ) && isset( $value['url'] ) ) { |
|
140 | + $value = $value['url']; |
|
141 | + } elseif ( is_numeric( $value ) ) { |
|
142 | + $value = absint( $value ); |
|
143 | + $value = wp_get_attachment_url( $value ); |
|
144 | + } else { |
|
145 | + $value = esc_url_raw( $value ); |
|
146 | + } |
|
147 | + |
|
148 | + return $value; |
|
149 | + |
|
150 | + } |
|
151 | 151 | |
152 | 152 | } |
@@ -10,7 +10,7 @@ discard block |
||
10 | 10 | |
11 | 11 | // Exit if accessed directly. |
12 | 12 | if ( ! defined( 'ABSPATH' ) ) { |
13 | - exit; |
|
13 | + exit; |
|
14 | 14 | } |
15 | 15 | |
16 | 16 | /** |
@@ -18,55 +18,55 @@ discard block |
||
18 | 18 | */ |
19 | 19 | class Upload extends \WP_Customize_Media_Control { |
20 | 20 | |
21 | - /** |
|
22 | - * Control type. |
|
23 | - * |
|
24 | - * @since 1.0.1 |
|
25 | - * @var string |
|
26 | - */ |
|
27 | - public $type = 'upload'; |
|
21 | + /** |
|
22 | + * Control type. |
|
23 | + * |
|
24 | + * @since 1.0.1 |
|
25 | + * @var string |
|
26 | + */ |
|
27 | + public $type = 'upload'; |
|
28 | 28 | |
29 | - /** |
|
30 | - * Media control mime type. |
|
31 | - * |
|
32 | - * @since 1.0.1 |
|
33 | - * @var string |
|
34 | - */ |
|
35 | - public $mime_type = ''; |
|
29 | + /** |
|
30 | + * Media control mime type. |
|
31 | + * |
|
32 | + * @since 1.0.1 |
|
33 | + * @var string |
|
34 | + */ |
|
35 | + public $mime_type = ''; |
|
36 | 36 | |
37 | - /** |
|
38 | - * Button labels. |
|
39 | - * |
|
40 | - * @since 1.0.1 |
|
41 | - * @var array |
|
42 | - */ |
|
43 | - public $button_labels = array(); |
|
37 | + /** |
|
38 | + * Button labels. |
|
39 | + * |
|
40 | + * @since 1.0.1 |
|
41 | + * @var array |
|
42 | + */ |
|
43 | + public $button_labels = array(); |
|
44 | 44 | |
45 | - /** |
|
46 | - * Refresh the parameters passed to the JavaScript via JSON. |
|
47 | - * |
|
48 | - * @since 1.0.1 |
|
49 | - * |
|
50 | - * @uses WP_Customize_Media_Control::to_json() |
|
51 | - */ |
|
52 | - public function to_json() { |
|
53 | - parent::to_json(); |
|
45 | + /** |
|
46 | + * Refresh the parameters passed to the JavaScript via JSON. |
|
47 | + * |
|
48 | + * @since 1.0.1 |
|
49 | + * |
|
50 | + * @uses WP_Customize_Media_Control::to_json() |
|
51 | + */ |
|
52 | + public function to_json() { |
|
53 | + parent::to_json(); |
|
54 | 54 | |
55 | - $value = $this->value(); |
|
55 | + $value = $this->value(); |
|
56 | 56 | |
57 | - if ( ! empty( $value ) ) { |
|
58 | - if ( is_array( $value ) && isset( $value['id'] ) ) { |
|
59 | - $attachment_id = $value['id']; |
|
60 | - } elseif ( is_numeric( $value ) ) { |
|
61 | - $attachment_id = absint( $value ); |
|
62 | - } elseif ( is_string( $value ) && ! is_numeric( $value ) ) { |
|
63 | - $attachment_id = attachment_url_to_postid( $value ); |
|
64 | - } |
|
57 | + if ( ! empty( $value ) ) { |
|
58 | + if ( is_array( $value ) && isset( $value['id'] ) ) { |
|
59 | + $attachment_id = $value['id']; |
|
60 | + } elseif ( is_numeric( $value ) ) { |
|
61 | + $attachment_id = absint( $value ); |
|
62 | + } elseif ( is_string( $value ) && ! is_numeric( $value ) ) { |
|
63 | + $attachment_id = attachment_url_to_postid( $value ); |
|
64 | + } |
|
65 | 65 | |
66 | - if ( ! empty( $attachment_id ) ) { |
|
67 | - $this->json['attachment'] = wp_prepare_attachment_for_js( $attachment_id ); |
|
68 | - } |
|
69 | - } |
|
70 | - } |
|
66 | + if ( ! empty( $attachment_id ) ) { |
|
67 | + $this->json['attachment'] = wp_prepare_attachment_for_js( $attachment_id ); |
|
68 | + } |
|
69 | + } |
|
70 | + } |
|
71 | 71 | |
72 | 72 | } |
@@ -22,111 +22,111 @@ |
||
22 | 22 | */ |
23 | 23 | class Webfonts { |
24 | 24 | |
25 | - /** |
|
26 | - * The Google object. |
|
27 | - * |
|
28 | - * @access protected |
|
29 | - * @since 1.0.0 |
|
30 | - * @var \Kirki\Module\Webfonts\Google |
|
31 | - */ |
|
32 | - protected $fonts_google; |
|
25 | + /** |
|
26 | + * The Google object. |
|
27 | + * |
|
28 | + * @access protected |
|
29 | + * @since 1.0.0 |
|
30 | + * @var \Kirki\Module\Webfonts\Google |
|
31 | + */ |
|
32 | + protected $fonts_google; |
|
33 | 33 | |
34 | - /** |
|
35 | - * An array of fields to be processed. |
|
36 | - * |
|
37 | - * @static |
|
38 | - * @access public |
|
39 | - * @since 1.0.0 |
|
40 | - * @var array |
|
41 | - */ |
|
42 | - public static $fields = []; |
|
34 | + /** |
|
35 | + * An array of fields to be processed. |
|
36 | + * |
|
37 | + * @static |
|
38 | + * @access public |
|
39 | + * @since 1.0.0 |
|
40 | + * @var array |
|
41 | + */ |
|
42 | + public static $fields = []; |
|
43 | 43 | |
44 | - /** |
|
45 | - * The class constructor |
|
46 | - * |
|
47 | - * @access public |
|
48 | - * @since 1.0.0 |
|
49 | - */ |
|
50 | - public function __construct() { |
|
44 | + /** |
|
45 | + * The class constructor |
|
46 | + * |
|
47 | + * @access public |
|
48 | + * @since 1.0.0 |
|
49 | + */ |
|
50 | + public function __construct() { |
|
51 | 51 | add_action( 'kirki_field_init', [ $this, 'field_init' ], 10, 2 ); |
52 | - add_action( 'wp_loaded', [ $this, 'run' ] ); |
|
53 | - } |
|
52 | + add_action( 'wp_loaded', [ $this, 'run' ] ); |
|
53 | + } |
|
54 | 54 | |
55 | - /** |
|
56 | - * Run on after_setup_theme. |
|
57 | - * |
|
58 | - * @access public |
|
59 | - * @since 1.0.0 |
|
60 | - */ |
|
61 | - public function run() { |
|
62 | - $this->fonts_google = Google::get_instance(); |
|
63 | - $this->init(); |
|
64 | - } |
|
55 | + /** |
|
56 | + * Run on after_setup_theme. |
|
57 | + * |
|
58 | + * @access public |
|
59 | + * @since 1.0.0 |
|
60 | + */ |
|
61 | + public function run() { |
|
62 | + $this->fonts_google = Google::get_instance(); |
|
63 | + $this->init(); |
|
64 | + } |
|
65 | 65 | |
66 | - /** |
|
67 | - * Init other objects depending on the method we'll be using. |
|
68 | - * |
|
69 | - * @access protected |
|
70 | - * @since 1.0.0 |
|
71 | - */ |
|
72 | - protected function init() { |
|
73 | - foreach ( array_keys( Kirki::$config ) as $config_id ) { |
|
74 | - if ( 'async' === $this->get_method() ) { |
|
75 | - new Async( $config_id, $this, $this->fonts_google ); |
|
76 | - } |
|
77 | - new Embed( $config_id, $this, $this->fonts_google ); |
|
78 | - } |
|
79 | - } |
|
66 | + /** |
|
67 | + * Init other objects depending on the method we'll be using. |
|
68 | + * |
|
69 | + * @access protected |
|
70 | + * @since 1.0.0 |
|
71 | + */ |
|
72 | + protected function init() { |
|
73 | + foreach ( array_keys( Kirki::$config ) as $config_id ) { |
|
74 | + if ( 'async' === $this->get_method() ) { |
|
75 | + new Async( $config_id, $this, $this->fonts_google ); |
|
76 | + } |
|
77 | + new Embed( $config_id, $this, $this->fonts_google ); |
|
78 | + } |
|
79 | + } |
|
80 | 80 | |
81 | - /** |
|
82 | - * Get the method we're going to use. |
|
83 | - * |
|
84 | - * @access public |
|
85 | - * @since 1.0.0 |
|
86 | - * @deprecated in 3.0.36. |
|
87 | - * @return string |
|
88 | - */ |
|
89 | - public function get_method() { |
|
90 | - return ( is_customize_preview() || is_admin() ) ? 'async' : 'embed'; |
|
91 | - } |
|
81 | + /** |
|
82 | + * Get the method we're going to use. |
|
83 | + * |
|
84 | + * @access public |
|
85 | + * @since 1.0.0 |
|
86 | + * @deprecated in 3.0.36. |
|
87 | + * @return string |
|
88 | + */ |
|
89 | + public function get_method() { |
|
90 | + return ( is_customize_preview() || is_admin() ) ? 'async' : 'embed'; |
|
91 | + } |
|
92 | 92 | |
93 | - /** |
|
94 | - * Runs when a field gets added. |
|
95 | - * Adds fields to this object so we can loop through them. |
|
96 | - * |
|
97 | - * @access public |
|
98 | - * @since 1.0.0 |
|
99 | - * @param array $args The field args. |
|
100 | - * @param Object $object The field object. |
|
101 | - * @return void |
|
102 | - */ |
|
103 | - public function field_init( $args, $object ) { |
|
104 | - if ( ! isset( $args['type'] ) && isset( $object->type ) ) { |
|
105 | - $args['type'] = $object->type; |
|
106 | - } |
|
93 | + /** |
|
94 | + * Runs when a field gets added. |
|
95 | + * Adds fields to this object so we can loop through them. |
|
96 | + * |
|
97 | + * @access public |
|
98 | + * @since 1.0.0 |
|
99 | + * @param array $args The field args. |
|
100 | + * @param Object $object The field object. |
|
101 | + * @return void |
|
102 | + */ |
|
103 | + public function field_init( $args, $object ) { |
|
104 | + if ( ! isset( $args['type'] ) && isset( $object->type ) ) { |
|
105 | + $args['type'] = $object->type; |
|
106 | + } |
|
107 | 107 | |
108 | - if ( ! isset( $args['type'] ) || $args['type'] !== 'kirki-typography' ) { |
|
109 | - return; |
|
110 | - } |
|
108 | + if ( ! isset( $args['type'] ) || $args['type'] !== 'kirki-typography' ) { |
|
109 | + return; |
|
110 | + } |
|
111 | 111 | |
112 | - // Use the settings ID as key: |
|
113 | - self::$fields[ $args['settings'] ] = $args; |
|
114 | - } |
|
112 | + // Use the settings ID as key: |
|
113 | + self::$fields[ $args['settings'] ] = $args; |
|
114 | + } |
|
115 | 115 | |
116 | 116 | |
117 | - /** |
|
118 | - * Goes through all our fields and then populates the $this->fonts property. |
|
119 | - * |
|
120 | - * @access public |
|
121 | - * @param string $config_id The config-ID. |
|
122 | - */ |
|
123 | - public function loop_fields( $config_id ) { |
|
124 | - foreach ( self::$fields as $field ) { |
|
125 | - if ( isset( $field['kirki_config'] ) && $config_id !== $field['kirki_config'] ) { |
|
126 | - continue; |
|
127 | - } |
|
117 | + /** |
|
118 | + * Goes through all our fields and then populates the $this->fonts property. |
|
119 | + * |
|
120 | + * @access public |
|
121 | + * @param string $config_id The config-ID. |
|
122 | + */ |
|
123 | + public function loop_fields( $config_id ) { |
|
124 | + foreach ( self::$fields as $field ) { |
|
125 | + if ( isset( $field['kirki_config'] ) && $config_id !== $field['kirki_config'] ) { |
|
126 | + continue; |
|
127 | + } |
|
128 | 128 | |
129 | - $this->fonts_google->generate_google_font( $field ); |
|
130 | - } |
|
131 | - } |
|
129 | + $this->fonts_google->generate_google_font( $field ); |
|
130 | + } |
|
131 | + } |
|
132 | 132 | } |
@@ -18,202 +18,202 @@ |
||
18 | 18 | */ |
19 | 19 | final class Fonts { |
20 | 20 | |
21 | - /** |
|
22 | - * The mode we'll be using to add google fonts. |
|
23 | - * This is a todo item, not yet functional. |
|
24 | - * |
|
25 | - * @static |
|
26 | - * @todo |
|
27 | - * @access public |
|
28 | - * @var string |
|
29 | - */ |
|
30 | - public static $mode = 'link'; |
|
31 | - |
|
32 | - /** |
|
33 | - * Holds a single instance of this object. |
|
34 | - * |
|
35 | - * @static |
|
36 | - * @access private |
|
37 | - * @var null|object |
|
38 | - */ |
|
39 | - private static $instance = null; |
|
40 | - |
|
41 | - /** |
|
42 | - * An array of our google fonts. |
|
43 | - * |
|
44 | - * @static |
|
45 | - * @access public |
|
46 | - * @var array |
|
47 | - */ |
|
48 | - public static $google_fonts = null; |
|
49 | - |
|
50 | - /** |
|
51 | - * The class constructor. |
|
52 | - */ |
|
53 | - private function __construct() {} |
|
54 | - |
|
55 | - /** |
|
56 | - * Get the one, true instance of this class. |
|
57 | - * Prevents performance issues since this is only loaded once. |
|
58 | - * |
|
59 | - * @return object Fonts |
|
60 | - */ |
|
61 | - public static function get_instance() { |
|
62 | - if ( null === self::$instance ) { |
|
63 | - self::$instance = new self(); |
|
64 | - } |
|
65 | - return self::$instance; |
|
66 | - } |
|
67 | - |
|
68 | - /** |
|
69 | - * Compile font options from different sources. |
|
70 | - * |
|
71 | - * @return array All available fonts. |
|
72 | - */ |
|
73 | - public static function get_all_fonts() { |
|
74 | - $standard_fonts = self::get_standard_fonts(); |
|
75 | - $google_fonts = self::get_google_fonts(); |
|
76 | - return apply_filters( 'kirki_fonts_all', array_merge( $standard_fonts, $google_fonts ) ); |
|
77 | - } |
|
78 | - |
|
79 | - /** |
|
80 | - * Return an array of standard websafe fonts. |
|
81 | - * |
|
82 | - * @return array Standard websafe fonts. |
|
83 | - */ |
|
84 | - public static function get_standard_fonts() { |
|
85 | - $standard_fonts = [ |
|
86 | - 'serif' => [ |
|
87 | - 'label' => 'Serif', |
|
88 | - 'stack' => 'Georgia,Times,"Times New Roman",serif', |
|
89 | - ], |
|
90 | - 'sans-serif' => [ |
|
91 | - 'label' => 'Sans Serif', |
|
92 | - 'stack' => '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif', |
|
93 | - ], |
|
94 | - 'monospace' => [ |
|
95 | - 'label' => 'Monospace', |
|
96 | - 'stack' => 'Monaco,"Lucida Sans Typewriter","Lucida Typewriter","Courier New",Courier,monospace', |
|
97 | - ], |
|
98 | - ]; |
|
99 | - |
|
100 | - return apply_filters( 'kirki_fonts_standard_fonts', $standard_fonts ); |
|
101 | - } |
|
102 | - |
|
103 | - /** |
|
104 | - * Return an array of all available Google Fonts. |
|
105 | - * |
|
106 | - * @return array All Google Fonts. |
|
107 | - */ |
|
108 | - public static function get_google_fonts() { |
|
109 | - if ( ! self::$google_fonts ) { |
|
110 | - $googlefonts = new GoogleFonts(); |
|
111 | - self::$google_fonts = $googlefonts->get_google_fonts(); |
|
112 | - } |
|
113 | - return self::$google_fonts; |
|
114 | - } |
|
115 | - |
|
116 | - /** |
|
117 | - * Returns an array of all available subsets. |
|
118 | - * |
|
119 | - * @static |
|
120 | - * @access public |
|
121 | - * @return array |
|
122 | - */ |
|
123 | - public static function get_google_font_subsets() { |
|
124 | - return [ |
|
125 | - 'cyrillic' => 'Cyrillic', |
|
126 | - 'cyrillic-ext' => 'Cyrillic Extended', |
|
127 | - 'devanagari' => 'Devanagari', |
|
128 | - 'greek' => 'Greek', |
|
129 | - 'greek-ext' => 'Greek Extended', |
|
130 | - 'khmer' => 'Khmer', |
|
131 | - 'latin' => 'Latin', |
|
132 | - 'latin-ext' => 'Latin Extended', |
|
133 | - 'vietnamese' => 'Vietnamese', |
|
134 | - 'hebrew' => 'Hebrew', |
|
135 | - 'arabic' => 'Arabic', |
|
136 | - 'bengali' => 'Bengali', |
|
137 | - 'gujarati' => 'Gujarati', |
|
138 | - 'tamil' => 'Tamil', |
|
139 | - 'telugu' => 'Telugu', |
|
140 | - 'thai' => 'Thai', |
|
141 | - ]; |
|
142 | - } |
|
143 | - |
|
144 | - /** |
|
145 | - * Dummy function to avoid issues with backwards-compatibility. |
|
146 | - * This is not functional, but it will prevent PHP Fatal errors. |
|
147 | - * |
|
148 | - * @static |
|
149 | - * @access public |
|
150 | - */ |
|
151 | - public static function get_google_font_uri() {} |
|
152 | - |
|
153 | - /** |
|
154 | - * Returns an array of all available variants. |
|
155 | - * |
|
156 | - * @static |
|
157 | - * @access public |
|
158 | - * @return array |
|
159 | - */ |
|
160 | - public static function get_all_variants() { |
|
161 | - return [ |
|
162 | - '100' => esc_html__( 'Ultra-Light 100', 'kirki' ), |
|
163 | - '100light' => esc_html__( 'Ultra-Light 100', 'kirki' ), |
|
164 | - '100italic' => esc_html__( 'Ultra-Light 100 Italic', 'kirki' ), |
|
165 | - '200' => esc_html__( 'Light 200', 'kirki' ), |
|
166 | - '200italic' => esc_html__( 'Light 200 Italic', 'kirki' ), |
|
167 | - '300' => esc_html__( 'Book 300', 'kirki' ), |
|
168 | - '300italic' => esc_html__( 'Book 300 Italic', 'kirki' ), |
|
169 | - '400' => esc_html__( 'Normal 400', 'kirki' ), |
|
170 | - 'regular' => esc_html__( 'Normal 400', 'kirki' ), |
|
171 | - 'italic' => esc_html__( 'Normal 400 Italic', 'kirki' ), |
|
172 | - '500' => esc_html__( 'Medium 500', 'kirki' ), |
|
173 | - '500italic' => esc_html__( 'Medium 500 Italic', 'kirki' ), |
|
174 | - '600' => esc_html__( 'Semi-Bold 600', 'kirki' ), |
|
175 | - '600bold' => esc_html__( 'Semi-Bold 600', 'kirki' ), |
|
176 | - '600italic' => esc_html__( 'Semi-Bold 600 Italic', 'kirki' ), |
|
177 | - '700' => esc_html__( 'Bold 700', 'kirki' ), |
|
178 | - '700italic' => esc_html__( 'Bold 700 Italic', 'kirki' ), |
|
179 | - '800' => esc_html__( 'Extra-Bold 800', 'kirki' ), |
|
180 | - '800bold' => esc_html__( 'Extra-Bold 800', 'kirki' ), |
|
181 | - '800italic' => esc_html__( 'Extra-Bold 800 Italic', 'kirki' ), |
|
182 | - '900' => esc_html__( 'Ultra-Bold 900', 'kirki' ), |
|
183 | - '900bold' => esc_html__( 'Ultra-Bold 900', 'kirki' ), |
|
184 | - '900italic' => esc_html__( 'Ultra-Bold 900 Italic', 'kirki' ), |
|
185 | - ]; |
|
186 | - } |
|
187 | - |
|
188 | - /** |
|
189 | - * Determine if a font-name is a valid google font or not. |
|
190 | - * |
|
191 | - * @static |
|
192 | - * @access public |
|
193 | - * @param string $fontname The name of the font we want to check. |
|
194 | - * @return bool |
|
195 | - */ |
|
196 | - public static function is_google_font( $fontname ) { |
|
197 | - if ( is_string( $fontname ) ) { |
|
198 | - $fonts = self::get_google_fonts(); |
|
199 | - return isset( $fonts[ $fontname ] ); |
|
200 | - } |
|
201 | - return false; |
|
202 | - } |
|
203 | - |
|
204 | - /** |
|
205 | - * Gets available options for a font. |
|
206 | - * |
|
207 | - * @static |
|
208 | - * @access public |
|
209 | - * @return array |
|
210 | - */ |
|
211 | - public static function get_font_choices() { |
|
212 | - |
|
213 | - $fonts = self::get_all_fonts(); |
|
214 | - $keys = array_keys( $fonts ); |
|
215 | - |
|
216 | - |
|
217 | - return array_combine( $keys, $keys ); |
|
218 | - } |
|
21 | + /** |
|
22 | + * The mode we'll be using to add google fonts. |
|
23 | + * This is a todo item, not yet functional. |
|
24 | + * |
|
25 | + * @static |
|
26 | + * @todo |
|
27 | + * @access public |
|
28 | + * @var string |
|
29 | + */ |
|
30 | + public static $mode = 'link'; |
|
31 | + |
|
32 | + /** |
|
33 | + * Holds a single instance of this object. |
|
34 | + * |
|
35 | + * @static |
|
36 | + * @access private |
|
37 | + * @var null|object |
|
38 | + */ |
|
39 | + private static $instance = null; |
|
40 | + |
|
41 | + /** |
|
42 | + * An array of our google fonts. |
|
43 | + * |
|
44 | + * @static |
|
45 | + * @access public |
|
46 | + * @var array |
|
47 | + */ |
|
48 | + public static $google_fonts = null; |
|
49 | + |
|
50 | + /** |
|
51 | + * The class constructor. |
|
52 | + */ |
|
53 | + private function __construct() {} |
|
54 | + |
|
55 | + /** |
|
56 | + * Get the one, true instance of this class. |
|
57 | + * Prevents performance issues since this is only loaded once. |
|
58 | + * |
|
59 | + * @return object Fonts |
|
60 | + */ |
|
61 | + public static function get_instance() { |
|
62 | + if ( null === self::$instance ) { |
|
63 | + self::$instance = new self(); |
|
64 | + } |
|
65 | + return self::$instance; |
|
66 | + } |
|
67 | + |
|
68 | + /** |
|
69 | + * Compile font options from different sources. |
|
70 | + * |
|
71 | + * @return array All available fonts. |
|
72 | + */ |
|
73 | + public static function get_all_fonts() { |
|
74 | + $standard_fonts = self::get_standard_fonts(); |
|
75 | + $google_fonts = self::get_google_fonts(); |
|
76 | + return apply_filters( 'kirki_fonts_all', array_merge( $standard_fonts, $google_fonts ) ); |
|
77 | + } |
|
78 | + |
|
79 | + /** |
|
80 | + * Return an array of standard websafe fonts. |
|
81 | + * |
|
82 | + * @return array Standard websafe fonts. |
|
83 | + */ |
|
84 | + public static function get_standard_fonts() { |
|
85 | + $standard_fonts = [ |
|
86 | + 'serif' => [ |
|
87 | + 'label' => 'Serif', |
|
88 | + 'stack' => 'Georgia,Times,"Times New Roman",serif', |
|
89 | + ], |
|
90 | + 'sans-serif' => [ |
|
91 | + 'label' => 'Sans Serif', |
|
92 | + 'stack' => '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif', |
|
93 | + ], |
|
94 | + 'monospace' => [ |
|
95 | + 'label' => 'Monospace', |
|
96 | + 'stack' => 'Monaco,"Lucida Sans Typewriter","Lucida Typewriter","Courier New",Courier,monospace', |
|
97 | + ], |
|
98 | + ]; |
|
99 | + |
|
100 | + return apply_filters( 'kirki_fonts_standard_fonts', $standard_fonts ); |
|
101 | + } |
|
102 | + |
|
103 | + /** |
|
104 | + * Return an array of all available Google Fonts. |
|
105 | + * |
|
106 | + * @return array All Google Fonts. |
|
107 | + */ |
|
108 | + public static function get_google_fonts() { |
|
109 | + if ( ! self::$google_fonts ) { |
|
110 | + $googlefonts = new GoogleFonts(); |
|
111 | + self::$google_fonts = $googlefonts->get_google_fonts(); |
|
112 | + } |
|
113 | + return self::$google_fonts; |
|
114 | + } |
|
115 | + |
|
116 | + /** |
|
117 | + * Returns an array of all available subsets. |
|
118 | + * |
|
119 | + * @static |
|
120 | + * @access public |
|
121 | + * @return array |
|
122 | + */ |
|
123 | + public static function get_google_font_subsets() { |
|
124 | + return [ |
|
125 | + 'cyrillic' => 'Cyrillic', |
|
126 | + 'cyrillic-ext' => 'Cyrillic Extended', |
|
127 | + 'devanagari' => 'Devanagari', |
|
128 | + 'greek' => 'Greek', |
|
129 | + 'greek-ext' => 'Greek Extended', |
|
130 | + 'khmer' => 'Khmer', |
|
131 | + 'latin' => 'Latin', |
|
132 | + 'latin-ext' => 'Latin Extended', |
|
133 | + 'vietnamese' => 'Vietnamese', |
|
134 | + 'hebrew' => 'Hebrew', |
|
135 | + 'arabic' => 'Arabic', |
|
136 | + 'bengali' => 'Bengali', |
|
137 | + 'gujarati' => 'Gujarati', |
|
138 | + 'tamil' => 'Tamil', |
|
139 | + 'telugu' => 'Telugu', |
|
140 | + 'thai' => 'Thai', |
|
141 | + ]; |
|
142 | + } |
|
143 | + |
|
144 | + /** |
|
145 | + * Dummy function to avoid issues with backwards-compatibility. |
|
146 | + * This is not functional, but it will prevent PHP Fatal errors. |
|
147 | + * |
|
148 | + * @static |
|
149 | + * @access public |
|
150 | + */ |
|
151 | + public static function get_google_font_uri() {} |
|
152 | + |
|
153 | + /** |
|
154 | + * Returns an array of all available variants. |
|
155 | + * |
|
156 | + * @static |
|
157 | + * @access public |
|
158 | + * @return array |
|
159 | + */ |
|
160 | + public static function get_all_variants() { |
|
161 | + return [ |
|
162 | + '100' => esc_html__( 'Ultra-Light 100', 'kirki' ), |
|
163 | + '100light' => esc_html__( 'Ultra-Light 100', 'kirki' ), |
|
164 | + '100italic' => esc_html__( 'Ultra-Light 100 Italic', 'kirki' ), |
|
165 | + '200' => esc_html__( 'Light 200', 'kirki' ), |
|
166 | + '200italic' => esc_html__( 'Light 200 Italic', 'kirki' ), |
|
167 | + '300' => esc_html__( 'Book 300', 'kirki' ), |
|
168 | + '300italic' => esc_html__( 'Book 300 Italic', 'kirki' ), |
|
169 | + '400' => esc_html__( 'Normal 400', 'kirki' ), |
|
170 | + 'regular' => esc_html__( 'Normal 400', 'kirki' ), |
|
171 | + 'italic' => esc_html__( 'Normal 400 Italic', 'kirki' ), |
|
172 | + '500' => esc_html__( 'Medium 500', 'kirki' ), |
|
173 | + '500italic' => esc_html__( 'Medium 500 Italic', 'kirki' ), |
|
174 | + '600' => esc_html__( 'Semi-Bold 600', 'kirki' ), |
|
175 | + '600bold' => esc_html__( 'Semi-Bold 600', 'kirki' ), |
|
176 | + '600italic' => esc_html__( 'Semi-Bold 600 Italic', 'kirki' ), |
|
177 | + '700' => esc_html__( 'Bold 700', 'kirki' ), |
|
178 | + '700italic' => esc_html__( 'Bold 700 Italic', 'kirki' ), |
|
179 | + '800' => esc_html__( 'Extra-Bold 800', 'kirki' ), |
|
180 | + '800bold' => esc_html__( 'Extra-Bold 800', 'kirki' ), |
|
181 | + '800italic' => esc_html__( 'Extra-Bold 800 Italic', 'kirki' ), |
|
182 | + '900' => esc_html__( 'Ultra-Bold 900', 'kirki' ), |
|
183 | + '900bold' => esc_html__( 'Ultra-Bold 900', 'kirki' ), |
|
184 | + '900italic' => esc_html__( 'Ultra-Bold 900 Italic', 'kirki' ), |
|
185 | + ]; |
|
186 | + } |
|
187 | + |
|
188 | + /** |
|
189 | + * Determine if a font-name is a valid google font or not. |
|
190 | + * |
|
191 | + * @static |
|
192 | + * @access public |
|
193 | + * @param string $fontname The name of the font we want to check. |
|
194 | + * @return bool |
|
195 | + */ |
|
196 | + public static function is_google_font( $fontname ) { |
|
197 | + if ( is_string( $fontname ) ) { |
|
198 | + $fonts = self::get_google_fonts(); |
|
199 | + return isset( $fonts[ $fontname ] ); |
|
200 | + } |
|
201 | + return false; |
|
202 | + } |
|
203 | + |
|
204 | + /** |
|
205 | + * Gets available options for a font. |
|
206 | + * |
|
207 | + * @static |
|
208 | + * @access public |
|
209 | + * @return array |
|
210 | + */ |
|
211 | + public static function get_font_choices() { |
|
212 | + |
|
213 | + $fonts = self::get_all_fonts(); |
|
214 | + $keys = array_keys( $fonts ); |
|
215 | + |
|
216 | + |
|
217 | + return array_combine( $keys, $keys ); |
|
218 | + } |
|
219 | 219 | } |
@@ -19,271 +19,271 @@ |
||
19 | 19 | */ |
20 | 20 | class Downloader { |
21 | 21 | |
22 | - /** |
|
23 | - * Get styles from URL. |
|
24 | - * |
|
25 | - * @access public |
|
26 | - * @since 3.1.0 |
|
27 | - * @param string $url The URL. |
|
28 | - * @return string |
|
29 | - */ |
|
30 | - public function get_styles( $url ) { |
|
31 | - $css = $this->get_cached_url_contents( $url ); |
|
32 | - return $this->get_local_font_styles( $css ); |
|
33 | - } |
|
34 | - |
|
35 | - /** |
|
36 | - * Get styles with fonts downloaded locally. |
|
37 | - * |
|
38 | - * @access protected |
|
39 | - * @since 3.1.0 |
|
40 | - * @param string $css The styles. |
|
41 | - * @return string |
|
42 | - */ |
|
43 | - protected function get_local_font_styles( $css ) { |
|
44 | - $files = $this->get_local_files_from_css( $css ); |
|
45 | - |
|
46 | - // Convert paths to URLs. |
|
47 | - foreach ( $files as $remote => $local ) { |
|
48 | - $files[ $remote ] = str_replace( WP_CONTENT_DIR, content_url(), $local ); |
|
49 | - } |
|
50 | - |
|
51 | - return str_replace( |
|
52 | - array_keys( $files ), |
|
53 | - array_values( $files ), |
|
54 | - $css |
|
55 | - ); |
|
56 | - } |
|
57 | - |
|
58 | - /** |
|
59 | - * Download files mentioned in our CSS locally. |
|
60 | - * |
|
61 | - * @access protected |
|
62 | - * @since 3.1.0 |
|
63 | - * @param string $css The CSS we want to parse. |
|
64 | - * @return array Returns an array of remote URLs and their local counterparts. |
|
65 | - */ |
|
66 | - protected function get_local_files_from_css( $css ) { |
|
67 | - $font_files = $this->get_files_from_css( $css ); |
|
68 | - $stored = get_option( 'kirki_downloaded_font_files', array() ); |
|
69 | - $change = false; // If in the end this is true, we need to update the cache option. |
|
70 | - |
|
71 | - // If the fonts folder don't exist, create it. |
|
72 | - if ( ! file_exists( WP_CONTENT_DIR . '/fonts' ) ) { |
|
73 | - $this->get_filesystem()->mkdir( WP_CONTENT_DIR . '/fonts', FS_CHMOD_DIR ); |
|
74 | - } |
|
75 | - |
|
76 | - foreach ( $font_files as $font_family => $files ) { |
|
77 | - |
|
78 | - // The folder path for this font-family. |
|
79 | - $folder_path = WP_CONTENT_DIR . '/fonts/' . $font_family; |
|
80 | - |
|
81 | - // If the folder doesn't exist, create it. |
|
82 | - if ( ! file_exists( $folder_path ) ) { |
|
83 | - $this->get_filesystem()->mkdir( $folder_path, FS_CHMOD_DIR ); |
|
84 | - } |
|
85 | - |
|
86 | - foreach ( $files as $url ) { |
|
87 | - |
|
88 | - // Get the filename. |
|
89 | - $filename = basename( wp_parse_url( $url, PHP_URL_PATH ) ); |
|
90 | - $font_path = $folder_path . '/' . $filename; |
|
91 | - |
|
92 | - if ( file_exists( $font_path ) ) { |
|
93 | - |
|
94 | - // Skip if already cached. |
|
95 | - if ( isset( $stored[ $url ] ) ) { |
|
96 | - continue; |
|
97 | - } |
|
98 | - |
|
99 | - $stored[ $url ] = $font_path; |
|
100 | - $change = true; |
|
101 | - } |
|
102 | - |
|
103 | - if ( ! function_exists( 'download_url' ) ) { |
|
104 | - require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/file.php' ); |
|
105 | - } |
|
106 | - |
|
107 | - // Download file to temporary location. |
|
108 | - $tmp_path = download_url( $url ); |
|
109 | - |
|
110 | - // Make sure there were no errors. |
|
111 | - if ( is_wp_error( $tmp_path ) ) { |
|
112 | - continue; |
|
113 | - } |
|
114 | - |
|
115 | - // Move temp file to final destination. |
|
116 | - $success = $this->get_filesystem()->move( $tmp_path, $font_path, true ); |
|
117 | - if ( $success ) { |
|
118 | - $stored[ $url ] = $font_path; |
|
119 | - $change = true; |
|
120 | - } |
|
121 | - } |
|
122 | - } |
|
123 | - |
|
124 | - if ( $change ) { |
|
125 | - update_option( 'kirki_downloaded_font_files', $stored ); |
|
126 | - } |
|
127 | - |
|
128 | - return $stored; |
|
129 | - } |
|
130 | - |
|
131 | - /** |
|
132 | - * Get cached url contents. |
|
133 | - * If a cache doesn't already exist, get the URL contents from remote |
|
134 | - * and cache the result. |
|
135 | - * |
|
136 | - * @access public |
|
137 | - * @since 3.1.0 |
|
138 | - * @param string $url The URL we want to get the contents from. |
|
139 | - * @param string $user_agent The user-agent to use for our request. |
|
140 | - * @return string Returns the remote URL contents. |
|
141 | - */ |
|
142 | - public function get_cached_url_contents( $url = '', $user_agent = null ) { |
|
143 | - |
|
144 | - // Try to retrieved cached response from the gfonts API. |
|
145 | - $contents = false; |
|
146 | - $cached_responses = get_transient( 'kirki_remote_url_contents' ); |
|
147 | - $cached_responses = ( $cached_responses && is_array( $cached_responses ) ) ? $cached_responses : array(); |
|
148 | - if ( isset( $cached_responses[ md5( $url . $user_agent ) ] ) ) { |
|
149 | - return $cached_responses[ md5( $url . $user_agent ) ]; |
|
150 | - } |
|
151 | - |
|
152 | - // Get the contents from remote. |
|
153 | - $contents = $this->get_url_contents( $url, $user_agent ); |
|
154 | - |
|
155 | - // If we got the contents successfully, store them in a transient. |
|
156 | - // We're using a transient and not an option because fonts get updated |
|
157 | - // so we want to be able to get the latest version weekly. |
|
158 | - if ( $contents ) { |
|
159 | - $cached_responses[ md5( $url . $user_agent ) ] = $contents; |
|
160 | - set_transient( 'kirki_remote_url_contents', $cached_responses, WEEK_IN_SECONDS ); |
|
161 | - } |
|
162 | - |
|
163 | - return $contents; |
|
164 | - } |
|
165 | - |
|
166 | - /** |
|
167 | - * Get remote file contents. |
|
168 | - * |
|
169 | - * @access public |
|
170 | - * @since 3.1.0 |
|
171 | - * @param string $url The URL we want to get the contents from. |
|
172 | - * @param string $user_agent The user-agent to use for our request. |
|
173 | - * @return string Returns the remote URL contents. |
|
174 | - */ |
|
175 | - public function get_url_contents( $url = '', $user_agent = null ) { |
|
176 | - |
|
177 | - if ( ! $user_agent ) { |
|
178 | - |
|
179 | - /** |
|
180 | - * The user-agent we want to use. |
|
181 | - * |
|
182 | - * For woff2 format, use'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0'. |
|
183 | - * The default user-agent is the only one compatible with woff (not woff2) |
|
184 | - * which also supports unicode ranges. |
|
185 | - */ |
|
186 | - $user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8'; |
|
187 | - } |
|
188 | - |
|
189 | - // Get the response. |
|
190 | - $response = wp_remote_get( $url, array( 'user-agent' => $user_agent ) ); |
|
191 | - |
|
192 | - // Early exit if there was an error. |
|
193 | - if ( is_wp_error( $response ) ) { |
|
194 | - return; |
|
195 | - } |
|
196 | - |
|
197 | - // Get the CSS from our response. |
|
198 | - $contents = wp_remote_retrieve_body( $response ); |
|
199 | - |
|
200 | - // Early exit if there was an error. |
|
201 | - if ( is_wp_error( $contents ) ) { |
|
202 | - return; |
|
203 | - } |
|
204 | - |
|
205 | - return $contents; |
|
206 | - } |
|
207 | - |
|
208 | - /** |
|
209 | - * Get font files from the CSS. |
|
210 | - * |
|
211 | - * @access public |
|
212 | - * @since 3.1.0 |
|
213 | - * @param string $css The CSS we want to parse. |
|
214 | - * @return array Returns an array of font-families and the font-files used. |
|
215 | - */ |
|
216 | - public function get_files_from_css( $css ) { |
|
217 | - |
|
218 | - $font_faces = explode( '@font-face', $css ); |
|
219 | - |
|
220 | - $result = array(); |
|
221 | - |
|
222 | - // Loop all our font-face declarations. |
|
223 | - foreach ( $font_faces as $font_face ) { |
|
224 | - |
|
225 | - // Make sure we only process styles inside this declaration. |
|
226 | - $style = explode( '}', $font_face )[0]; |
|
227 | - |
|
228 | - // Sanity check. |
|
229 | - if ( false === strpos( $style, 'font-family' ) ) { |
|
230 | - continue; |
|
231 | - } |
|
232 | - |
|
233 | - // Get an array of our font-families. |
|
234 | - preg_match_all( '/font-family.*?\;/', $style, $matched_font_families ); |
|
235 | - |
|
236 | - // Get an array of our font-files. |
|
237 | - preg_match_all( '/url\(.*?\)/i', $style, $matched_font_files ); |
|
238 | - |
|
239 | - // Get the font-family name. |
|
240 | - $font_family = 'unknown'; |
|
241 | - if ( isset( $matched_font_families[0] ) && isset( $matched_font_families[0][0] ) ) { |
|
242 | - $font_family = rtrim( ltrim( $matched_font_families[0][0], 'font-family:' ), ';' ); |
|
243 | - $font_family = trim( str_replace( array( "'", ';' ), '', $font_family ) ); |
|
244 | - $font_family = sanitize_key( strtolower( str_replace( ' ', '-', $font_family ) ) ); |
|
245 | - } |
|
246 | - |
|
247 | - // Make sure the font-family is set in our array. |
|
248 | - if ( ! isset( $result[ $font_family ] ) ) { |
|
249 | - $result[ $font_family ] = array(); |
|
250 | - } |
|
251 | - |
|
252 | - // Get files for this font-family and add them to the array. |
|
253 | - |
|
254 | - foreach ( $matched_font_files as $match ) { |
|
255 | - |
|
256 | - // Sanity check. |
|
257 | - if ( ! isset( $match[0] ) ) { |
|
258 | - continue; |
|
259 | - } |
|
260 | - |
|
261 | - // Add the file URL. |
|
262 | - $result[ $font_family ][] = rtrim( ltrim( $match[0], 'url(' ), ')' ); |
|
263 | - } |
|
264 | - |
|
265 | - // Make sure we have unique items. |
|
266 | - // We're using array_flip here instead of array_unique for improved performance. |
|
267 | - $result[ $font_family ] = array_flip( array_flip( $result[ $font_family ] ) ); |
|
268 | - } |
|
269 | - return $result; |
|
270 | - } |
|
271 | - |
|
272 | - /** |
|
273 | - * Get the filesystem. |
|
274 | - * |
|
275 | - * @access protected |
|
276 | - * @since 3.1.0 |
|
277 | - * @return WP_Filesystem |
|
278 | - */ |
|
279 | - protected function get_filesystem() { |
|
280 | - global $wp_filesystem; |
|
281 | - if ( ! $wp_filesystem ) { |
|
282 | - if ( ! function_exists( 'WP_Filesystem' ) ) { |
|
283 | - require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/file.php' ); |
|
284 | - } |
|
285 | - WP_Filesystem(); |
|
286 | - } |
|
287 | - return $wp_filesystem; |
|
288 | - } |
|
22 | + /** |
|
23 | + * Get styles from URL. |
|
24 | + * |
|
25 | + * @access public |
|
26 | + * @since 3.1.0 |
|
27 | + * @param string $url The URL. |
|
28 | + * @return string |
|
29 | + */ |
|
30 | + public function get_styles( $url ) { |
|
31 | + $css = $this->get_cached_url_contents( $url ); |
|
32 | + return $this->get_local_font_styles( $css ); |
|
33 | + } |
|
34 | + |
|
35 | + /** |
|
36 | + * Get styles with fonts downloaded locally. |
|
37 | + * |
|
38 | + * @access protected |
|
39 | + * @since 3.1.0 |
|
40 | + * @param string $css The styles. |
|
41 | + * @return string |
|
42 | + */ |
|
43 | + protected function get_local_font_styles( $css ) { |
|
44 | + $files = $this->get_local_files_from_css( $css ); |
|
45 | + |
|
46 | + // Convert paths to URLs. |
|
47 | + foreach ( $files as $remote => $local ) { |
|
48 | + $files[ $remote ] = str_replace( WP_CONTENT_DIR, content_url(), $local ); |
|
49 | + } |
|
50 | + |
|
51 | + return str_replace( |
|
52 | + array_keys( $files ), |
|
53 | + array_values( $files ), |
|
54 | + $css |
|
55 | + ); |
|
56 | + } |
|
57 | + |
|
58 | + /** |
|
59 | + * Download files mentioned in our CSS locally. |
|
60 | + * |
|
61 | + * @access protected |
|
62 | + * @since 3.1.0 |
|
63 | + * @param string $css The CSS we want to parse. |
|
64 | + * @return array Returns an array of remote URLs and their local counterparts. |
|
65 | + */ |
|
66 | + protected function get_local_files_from_css( $css ) { |
|
67 | + $font_files = $this->get_files_from_css( $css ); |
|
68 | + $stored = get_option( 'kirki_downloaded_font_files', array() ); |
|
69 | + $change = false; // If in the end this is true, we need to update the cache option. |
|
70 | + |
|
71 | + // If the fonts folder don't exist, create it. |
|
72 | + if ( ! file_exists( WP_CONTENT_DIR . '/fonts' ) ) { |
|
73 | + $this->get_filesystem()->mkdir( WP_CONTENT_DIR . '/fonts', FS_CHMOD_DIR ); |
|
74 | + } |
|
75 | + |
|
76 | + foreach ( $font_files as $font_family => $files ) { |
|
77 | + |
|
78 | + // The folder path for this font-family. |
|
79 | + $folder_path = WP_CONTENT_DIR . '/fonts/' . $font_family; |
|
80 | + |
|
81 | + // If the folder doesn't exist, create it. |
|
82 | + if ( ! file_exists( $folder_path ) ) { |
|
83 | + $this->get_filesystem()->mkdir( $folder_path, FS_CHMOD_DIR ); |
|
84 | + } |
|
85 | + |
|
86 | + foreach ( $files as $url ) { |
|
87 | + |
|
88 | + // Get the filename. |
|
89 | + $filename = basename( wp_parse_url( $url, PHP_URL_PATH ) ); |
|
90 | + $font_path = $folder_path . '/' . $filename; |
|
91 | + |
|
92 | + if ( file_exists( $font_path ) ) { |
|
93 | + |
|
94 | + // Skip if already cached. |
|
95 | + if ( isset( $stored[ $url ] ) ) { |
|
96 | + continue; |
|
97 | + } |
|
98 | + |
|
99 | + $stored[ $url ] = $font_path; |
|
100 | + $change = true; |
|
101 | + } |
|
102 | + |
|
103 | + if ( ! function_exists( 'download_url' ) ) { |
|
104 | + require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/file.php' ); |
|
105 | + } |
|
106 | + |
|
107 | + // Download file to temporary location. |
|
108 | + $tmp_path = download_url( $url ); |
|
109 | + |
|
110 | + // Make sure there were no errors. |
|
111 | + if ( is_wp_error( $tmp_path ) ) { |
|
112 | + continue; |
|
113 | + } |
|
114 | + |
|
115 | + // Move temp file to final destination. |
|
116 | + $success = $this->get_filesystem()->move( $tmp_path, $font_path, true ); |
|
117 | + if ( $success ) { |
|
118 | + $stored[ $url ] = $font_path; |
|
119 | + $change = true; |
|
120 | + } |
|
121 | + } |
|
122 | + } |
|
123 | + |
|
124 | + if ( $change ) { |
|
125 | + update_option( 'kirki_downloaded_font_files', $stored ); |
|
126 | + } |
|
127 | + |
|
128 | + return $stored; |
|
129 | + } |
|
130 | + |
|
131 | + /** |
|
132 | + * Get cached url contents. |
|
133 | + * If a cache doesn't already exist, get the URL contents from remote |
|
134 | + * and cache the result. |
|
135 | + * |
|
136 | + * @access public |
|
137 | + * @since 3.1.0 |
|
138 | + * @param string $url The URL we want to get the contents from. |
|
139 | + * @param string $user_agent The user-agent to use for our request. |
|
140 | + * @return string Returns the remote URL contents. |
|
141 | + */ |
|
142 | + public function get_cached_url_contents( $url = '', $user_agent = null ) { |
|
143 | + |
|
144 | + // Try to retrieved cached response from the gfonts API. |
|
145 | + $contents = false; |
|
146 | + $cached_responses = get_transient( 'kirki_remote_url_contents' ); |
|
147 | + $cached_responses = ( $cached_responses && is_array( $cached_responses ) ) ? $cached_responses : array(); |
|
148 | + if ( isset( $cached_responses[ md5( $url . $user_agent ) ] ) ) { |
|
149 | + return $cached_responses[ md5( $url . $user_agent ) ]; |
|
150 | + } |
|
151 | + |
|
152 | + // Get the contents from remote. |
|
153 | + $contents = $this->get_url_contents( $url, $user_agent ); |
|
154 | + |
|
155 | + // If we got the contents successfully, store them in a transient. |
|
156 | + // We're using a transient and not an option because fonts get updated |
|
157 | + // so we want to be able to get the latest version weekly. |
|
158 | + if ( $contents ) { |
|
159 | + $cached_responses[ md5( $url . $user_agent ) ] = $contents; |
|
160 | + set_transient( 'kirki_remote_url_contents', $cached_responses, WEEK_IN_SECONDS ); |
|
161 | + } |
|
162 | + |
|
163 | + return $contents; |
|
164 | + } |
|
165 | + |
|
166 | + /** |
|
167 | + * Get remote file contents. |
|
168 | + * |
|
169 | + * @access public |
|
170 | + * @since 3.1.0 |
|
171 | + * @param string $url The URL we want to get the contents from. |
|
172 | + * @param string $user_agent The user-agent to use for our request. |
|
173 | + * @return string Returns the remote URL contents. |
|
174 | + */ |
|
175 | + public function get_url_contents( $url = '', $user_agent = null ) { |
|
176 | + |
|
177 | + if ( ! $user_agent ) { |
|
178 | + |
|
179 | + /** |
|
180 | + * The user-agent we want to use. |
|
181 | + * |
|
182 | + * For woff2 format, use'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0'. |
|
183 | + * The default user-agent is the only one compatible with woff (not woff2) |
|
184 | + * which also supports unicode ranges. |
|
185 | + */ |
|
186 | + $user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8'; |
|
187 | + } |
|
188 | + |
|
189 | + // Get the response. |
|
190 | + $response = wp_remote_get( $url, array( 'user-agent' => $user_agent ) ); |
|
191 | + |
|
192 | + // Early exit if there was an error. |
|
193 | + if ( is_wp_error( $response ) ) { |
|
194 | + return; |
|
195 | + } |
|
196 | + |
|
197 | + // Get the CSS from our response. |
|
198 | + $contents = wp_remote_retrieve_body( $response ); |
|
199 | + |
|
200 | + // Early exit if there was an error. |
|
201 | + if ( is_wp_error( $contents ) ) { |
|
202 | + return; |
|
203 | + } |
|
204 | + |
|
205 | + return $contents; |
|
206 | + } |
|
207 | + |
|
208 | + /** |
|
209 | + * Get font files from the CSS. |
|
210 | + * |
|
211 | + * @access public |
|
212 | + * @since 3.1.0 |
|
213 | + * @param string $css The CSS we want to parse. |
|
214 | + * @return array Returns an array of font-families and the font-files used. |
|
215 | + */ |
|
216 | + public function get_files_from_css( $css ) { |
|
217 | + |
|
218 | + $font_faces = explode( '@font-face', $css ); |
|
219 | + |
|
220 | + $result = array(); |
|
221 | + |
|
222 | + // Loop all our font-face declarations. |
|
223 | + foreach ( $font_faces as $font_face ) { |
|
224 | + |
|
225 | + // Make sure we only process styles inside this declaration. |
|
226 | + $style = explode( '}', $font_face )[0]; |
|
227 | + |
|
228 | + // Sanity check. |
|
229 | + if ( false === strpos( $style, 'font-family' ) ) { |
|
230 | + continue; |
|
231 | + } |
|
232 | + |
|
233 | + // Get an array of our font-families. |
|
234 | + preg_match_all( '/font-family.*?\;/', $style, $matched_font_families ); |
|
235 | + |
|
236 | + // Get an array of our font-files. |
|
237 | + preg_match_all( '/url\(.*?\)/i', $style, $matched_font_files ); |
|
238 | + |
|
239 | + // Get the font-family name. |
|
240 | + $font_family = 'unknown'; |
|
241 | + if ( isset( $matched_font_families[0] ) && isset( $matched_font_families[0][0] ) ) { |
|
242 | + $font_family = rtrim( ltrim( $matched_font_families[0][0], 'font-family:' ), ';' ); |
|
243 | + $font_family = trim( str_replace( array( "'", ';' ), '', $font_family ) ); |
|
244 | + $font_family = sanitize_key( strtolower( str_replace( ' ', '-', $font_family ) ) ); |
|
245 | + } |
|
246 | + |
|
247 | + // Make sure the font-family is set in our array. |
|
248 | + if ( ! isset( $result[ $font_family ] ) ) { |
|
249 | + $result[ $font_family ] = array(); |
|
250 | + } |
|
251 | + |
|
252 | + // Get files for this font-family and add them to the array. |
|
253 | + |
|
254 | + foreach ( $matched_font_files as $match ) { |
|
255 | + |
|
256 | + // Sanity check. |
|
257 | + if ( ! isset( $match[0] ) ) { |
|
258 | + continue; |
|
259 | + } |
|
260 | + |
|
261 | + // Add the file URL. |
|
262 | + $result[ $font_family ][] = rtrim( ltrim( $match[0], 'url(' ), ')' ); |
|
263 | + } |
|
264 | + |
|
265 | + // Make sure we have unique items. |
|
266 | + // We're using array_flip here instead of array_unique for improved performance. |
|
267 | + $result[ $font_family ] = array_flip( array_flip( $result[ $font_family ] ) ); |
|
268 | + } |
|
269 | + return $result; |
|
270 | + } |
|
271 | + |
|
272 | + /** |
|
273 | + * Get the filesystem. |
|
274 | + * |
|
275 | + * @access protected |
|
276 | + * @since 3.1.0 |
|
277 | + * @return WP_Filesystem |
|
278 | + */ |
|
279 | + protected function get_filesystem() { |
|
280 | + global $wp_filesystem; |
|
281 | + if ( ! $wp_filesystem ) { |
|
282 | + if ( ! function_exists( 'WP_Filesystem' ) ) { |
|
283 | + require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/file.php' ); |
|
284 | + } |
|
285 | + WP_Filesystem(); |
|
286 | + } |
|
287 | + return $wp_filesystem; |
|
288 | + } |
|
289 | 289 | } |
@@ -18,178 +18,178 @@ |
||
18 | 18 | */ |
19 | 19 | final class Embed { |
20 | 20 | |
21 | - /** |
|
22 | - * The config ID. |
|
23 | - * |
|
24 | - * @access protected |
|
25 | - * @since 1.0.0 |
|
26 | - * @var string |
|
27 | - */ |
|
28 | - protected $config_id; |
|
29 | - |
|
30 | - /** |
|
31 | - * The \Kirki\Module\Webfonts object. |
|
32 | - * |
|
33 | - * @access protected |
|
34 | - * @since 1.0.0 |
|
35 | - * @var object |
|
36 | - */ |
|
37 | - protected $webfonts; |
|
38 | - |
|
39 | - /** |
|
40 | - * The \Kirki\Module\Webfonts\Google object. |
|
41 | - * |
|
42 | - * @access protected |
|
43 | - * @since 1.0.0 |
|
44 | - * @var object |
|
45 | - */ |
|
46 | - protected $googlefonts; |
|
47 | - |
|
48 | - /** |
|
49 | - * Fonts to load. |
|
50 | - * |
|
51 | - * @access protected |
|
52 | - * @since 1.0.0 |
|
53 | - * @var array |
|
54 | - */ |
|
55 | - protected $fonts_to_load = []; |
|
56 | - |
|
57 | - /** |
|
58 | - * Constructor. |
|
59 | - * |
|
60 | - * @access public |
|
61 | - * @since 1.0.0 |
|
62 | - * @param string $config_id The config-ID. |
|
63 | - * @param object $webfonts The \Kirki\Module\Webfonts object. |
|
64 | - * @param object $googlefonts The \Kirki\Module\Webfonts\Google object. |
|
65 | - * @param array $args Extra args we want to pass. |
|
66 | - */ |
|
67 | - public function __construct( $config_id, $webfonts, $googlefonts, $args = [] ) { |
|
68 | - $this->config_id = $config_id; |
|
69 | - $this->webfonts = $webfonts; |
|
70 | - $this->googlefonts = $googlefonts; |
|
71 | - |
|
72 | - add_action( 'wp', [ $this, 'init' ], 9 ); |
|
73 | - // add_filter( 'wp_resource_hints', [ $this, 'resource_hints' ], 10, 2 ); |
|
74 | - } |
|
75 | - |
|
76 | - /** |
|
77 | - * Init. |
|
78 | - * |
|
79 | - * @access public |
|
80 | - * @since 1.0.0 |
|
81 | - * @return void |
|
82 | - */ |
|
83 | - public function init() { |
|
84 | - $this->populate_fonts(); |
|
85 | - add_action( 'kirki_dynamic_css', [ $this, 'the_css' ] ); |
|
86 | - } |
|
87 | - |
|
88 | - /** |
|
89 | - * Add preconnect for Google Fonts. |
|
90 | - * |
|
91 | - * @access public |
|
92 | - * @param array $urls URLs to print for resource hints. |
|
93 | - * @param string $relation_type The relation type the URLs are printed. |
|
94 | - * @return array $urls URLs to print for resource hints. |
|
95 | - */ |
|
96 | - public function resource_hints( $urls, $relation_type ) { |
|
97 | - $fonts_to_load = $this->googlefonts->fonts; |
|
98 | - |
|
99 | - if ( ! empty( $fonts_to_load ) && 'preconnect' === $relation_type ) { |
|
100 | - $urls[] = [ |
|
101 | - 'href' => 'https://fonts.gstatic.com', |
|
102 | - 'crossorigin', |
|
103 | - ]; |
|
104 | - } |
|
105 | - |
|
106 | - return $urls; |
|
107 | - } |
|
108 | - |
|
109 | - /** |
|
110 | - * Webfont Loader for Google Fonts. |
|
111 | - * |
|
112 | - * @access public |
|
113 | - * @since 1.0.0 |
|
114 | - */ |
|
115 | - public function populate_fonts() { |
|
116 | - |
|
117 | - // Go through our fields and populate $this->fonts. |
|
118 | - $this->webfonts->loop_fields( $this->config_id ); |
|
119 | - |
|
120 | - $this->googlefonts->fonts = apply_filters( 'kirki_enqueue_google_fonts', $this->googlefonts->fonts ); |
|
121 | - |
|
122 | - // Goes through $this->fonts and adds or removes things as needed. |
|
123 | - $this->googlefonts->process_fonts(); |
|
124 | - |
|
125 | - foreach ( $this->googlefonts->fonts as $font => $weights ) { |
|
126 | - foreach ( $weights as $key => $value ) { |
|
127 | - if ( 'italic' === $value ) { |
|
128 | - $weights[ $key ] = '400i'; |
|
129 | - } else { |
|
130 | - $weights[ $key ] = str_replace( [ 'regular', 'bold', 'italic' ], [ '400', '', 'i' ], $value ); |
|
131 | - } |
|
132 | - } |
|
133 | - $this->fonts_to_load[] = [ |
|
134 | - 'family' => $font, |
|
135 | - 'weights' => $weights, |
|
136 | - ]; |
|
137 | - } |
|
138 | - } |
|
139 | - |
|
140 | - /** |
|
141 | - * Webfont Loader script for Google Fonts. |
|
142 | - * |
|
143 | - * @access public |
|
144 | - * @since 1.0.0 |
|
145 | - */ |
|
146 | - public function the_css() { |
|
147 | - foreach ( $this->fonts_to_load as $font ) { |
|
148 | - |
|
149 | - $family = str_replace( ' ', '+', trim( $font['family'] ) ); |
|
150 | - $weights = join( ',', $font['weights'] ); |
|
151 | - $url = "https://fonts.googleapis.com/css?family={$family}:{$weights}&subset=cyrillic,cyrillic-ext,devanagari,greek,greek-ext,khmer,latin,latin-ext,vietnamese,hebrew,arabic,bengali,gujarati,tamil,telugu,thai&display=swap"; |
|
152 | - |
|
153 | - $downloader = new Downloader(); |
|
154 | - $contents = $downloader->get_styles( $url ); |
|
155 | - |
|
156 | - if ( $contents ) { |
|
157 | - /** |
|
158 | - * Note to code reviewers: |
|
159 | - * |
|
160 | - * Though all output should be run through an escaping function, this is pure CSS |
|
161 | - * and it is added on a call that has a PHP `header( 'Content-type: text/css' );`. |
|
162 | - * No code, script or anything else can be executed from inside a stylesheet. |
|
163 | - * For extra security we're using the wp_strip_all_tags() function here |
|
164 | - * just to make sure there's no <script> tags in there or anything else. |
|
165 | - */ |
|
166 | - echo wp_strip_all_tags( $contents ); // phpcs:ignore WordPress.Security.EscapeOutput |
|
167 | - } |
|
168 | - } |
|
169 | - } |
|
170 | - |
|
171 | - /** |
|
172 | - * Downloads font-files locally and uses the local files instead of the ones from Google's servers. |
|
173 | - * This addresses any and all GDPR concerns, as well as firewalls that exist in some parts of the world. |
|
174 | - * |
|
175 | - * @access private |
|
176 | - * @since 1.0.0 |
|
177 | - * @param string $css The CSS with original URLs. |
|
178 | - * @return string The CSS with local URLs. |
|
179 | - */ |
|
180 | - private function use_local_files( $css ) { |
|
181 | - preg_match_all( '/https\:.*?\.woff/', $css, $matches ); |
|
182 | - |
|
183 | - $matches = array_shift( $matches ); |
|
184 | - |
|
185 | - foreach ( $matches as $match ) { |
|
186 | - if ( 0 === strpos( $match, 'https://fonts.gstatic.com' ) ) { |
|
187 | - $new_url = Helper::download_font_file( $match ); |
|
188 | - if ( $new_url ) { |
|
189 | - $css = str_replace( $match, $new_url, $css ); |
|
190 | - } |
|
191 | - } |
|
192 | - } |
|
193 | - return $css; |
|
194 | - } |
|
21 | + /** |
|
22 | + * The config ID. |
|
23 | + * |
|
24 | + * @access protected |
|
25 | + * @since 1.0.0 |
|
26 | + * @var string |
|
27 | + */ |
|
28 | + protected $config_id; |
|
29 | + |
|
30 | + /** |
|
31 | + * The \Kirki\Module\Webfonts object. |
|
32 | + * |
|
33 | + * @access protected |
|
34 | + * @since 1.0.0 |
|
35 | + * @var object |
|
36 | + */ |
|
37 | + protected $webfonts; |
|
38 | + |
|
39 | + /** |
|
40 | + * The \Kirki\Module\Webfonts\Google object. |
|
41 | + * |
|
42 | + * @access protected |
|
43 | + * @since 1.0.0 |
|
44 | + * @var object |
|
45 | + */ |
|
46 | + protected $googlefonts; |
|
47 | + |
|
48 | + /** |
|
49 | + * Fonts to load. |
|
50 | + * |
|
51 | + * @access protected |
|
52 | + * @since 1.0.0 |
|
53 | + * @var array |
|
54 | + */ |
|
55 | + protected $fonts_to_load = []; |
|
56 | + |
|
57 | + /** |
|
58 | + * Constructor. |
|
59 | + * |
|
60 | + * @access public |
|
61 | + * @since 1.0.0 |
|
62 | + * @param string $config_id The config-ID. |
|
63 | + * @param object $webfonts The \Kirki\Module\Webfonts object. |
|
64 | + * @param object $googlefonts The \Kirki\Module\Webfonts\Google object. |
|
65 | + * @param array $args Extra args we want to pass. |
|
66 | + */ |
|
67 | + public function __construct( $config_id, $webfonts, $googlefonts, $args = [] ) { |
|
68 | + $this->config_id = $config_id; |
|
69 | + $this->webfonts = $webfonts; |
|
70 | + $this->googlefonts = $googlefonts; |
|
71 | + |
|
72 | + add_action( 'wp', [ $this, 'init' ], 9 ); |
|
73 | + // add_filter( 'wp_resource_hints', [ $this, 'resource_hints' ], 10, 2 ); |
|
74 | + } |
|
75 | + |
|
76 | + /** |
|
77 | + * Init. |
|
78 | + * |
|
79 | + * @access public |
|
80 | + * @since 1.0.0 |
|
81 | + * @return void |
|
82 | + */ |
|
83 | + public function init() { |
|
84 | + $this->populate_fonts(); |
|
85 | + add_action( 'kirki_dynamic_css', [ $this, 'the_css' ] ); |
|
86 | + } |
|
87 | + |
|
88 | + /** |
|
89 | + * Add preconnect for Google Fonts. |
|
90 | + * |
|
91 | + * @access public |
|
92 | + * @param array $urls URLs to print for resource hints. |
|
93 | + * @param string $relation_type The relation type the URLs are printed. |
|
94 | + * @return array $urls URLs to print for resource hints. |
|
95 | + */ |
|
96 | + public function resource_hints( $urls, $relation_type ) { |
|
97 | + $fonts_to_load = $this->googlefonts->fonts; |
|
98 | + |
|
99 | + if ( ! empty( $fonts_to_load ) && 'preconnect' === $relation_type ) { |
|
100 | + $urls[] = [ |
|
101 | + 'href' => 'https://fonts.gstatic.com', |
|
102 | + 'crossorigin', |
|
103 | + ]; |
|
104 | + } |
|
105 | + |
|
106 | + return $urls; |
|
107 | + } |
|
108 | + |
|
109 | + /** |
|
110 | + * Webfont Loader for Google Fonts. |
|
111 | + * |
|
112 | + * @access public |
|
113 | + * @since 1.0.0 |
|
114 | + */ |
|
115 | + public function populate_fonts() { |
|
116 | + |
|
117 | + // Go through our fields and populate $this->fonts. |
|
118 | + $this->webfonts->loop_fields( $this->config_id ); |
|
119 | + |
|
120 | + $this->googlefonts->fonts = apply_filters( 'kirki_enqueue_google_fonts', $this->googlefonts->fonts ); |
|
121 | + |
|
122 | + // Goes through $this->fonts and adds or removes things as needed. |
|
123 | + $this->googlefonts->process_fonts(); |
|
124 | + |
|
125 | + foreach ( $this->googlefonts->fonts as $font => $weights ) { |
|
126 | + foreach ( $weights as $key => $value ) { |
|
127 | + if ( 'italic' === $value ) { |
|
128 | + $weights[ $key ] = '400i'; |
|
129 | + } else { |
|
130 | + $weights[ $key ] = str_replace( [ 'regular', 'bold', 'italic' ], [ '400', '', 'i' ], $value ); |
|
131 | + } |
|
132 | + } |
|
133 | + $this->fonts_to_load[] = [ |
|
134 | + 'family' => $font, |
|
135 | + 'weights' => $weights, |
|
136 | + ]; |
|
137 | + } |
|
138 | + } |
|
139 | + |
|
140 | + /** |
|
141 | + * Webfont Loader script for Google Fonts. |
|
142 | + * |
|
143 | + * @access public |
|
144 | + * @since 1.0.0 |
|
145 | + */ |
|
146 | + public function the_css() { |
|
147 | + foreach ( $this->fonts_to_load as $font ) { |
|
148 | + |
|
149 | + $family = str_replace( ' ', '+', trim( $font['family'] ) ); |
|
150 | + $weights = join( ',', $font['weights'] ); |
|
151 | + $url = "https://fonts.googleapis.com/css?family={$family}:{$weights}&subset=cyrillic,cyrillic-ext,devanagari,greek,greek-ext,khmer,latin,latin-ext,vietnamese,hebrew,arabic,bengali,gujarati,tamil,telugu,thai&display=swap"; |
|
152 | + |
|
153 | + $downloader = new Downloader(); |
|
154 | + $contents = $downloader->get_styles( $url ); |
|
155 | + |
|
156 | + if ( $contents ) { |
|
157 | + /** |
|
158 | + * Note to code reviewers: |
|
159 | + * |
|
160 | + * Though all output should be run through an escaping function, this is pure CSS |
|
161 | + * and it is added on a call that has a PHP `header( 'Content-type: text/css' );`. |
|
162 | + * No code, script or anything else can be executed from inside a stylesheet. |
|
163 | + * For extra security we're using the wp_strip_all_tags() function here |
|
164 | + * just to make sure there's no <script> tags in there or anything else. |
|
165 | + */ |
|
166 | + echo wp_strip_all_tags( $contents ); // phpcs:ignore WordPress.Security.EscapeOutput |
|
167 | + } |
|
168 | + } |
|
169 | + } |
|
170 | + |
|
171 | + /** |
|
172 | + * Downloads font-files locally and uses the local files instead of the ones from Google's servers. |
|
173 | + * This addresses any and all GDPR concerns, as well as firewalls that exist in some parts of the world. |
|
174 | + * |
|
175 | + * @access private |
|
176 | + * @since 1.0.0 |
|
177 | + * @param string $css The CSS with original URLs. |
|
178 | + * @return string The CSS with local URLs. |
|
179 | + */ |
|
180 | + private function use_local_files( $css ) { |
|
181 | + preg_match_all( '/https\:.*?\.woff/', $css, $matches ); |
|
182 | + |
|
183 | + $matches = array_shift( $matches ); |
|
184 | + |
|
185 | + foreach ( $matches as $match ) { |
|
186 | + if ( 0 === strpos( $match, 'https://fonts.gstatic.com' ) ) { |
|
187 | + $new_url = Helper::download_font_file( $match ); |
|
188 | + if ( $new_url ) { |
|
189 | + $css = str_replace( $match, $new_url, $css ); |
|
190 | + } |
|
191 | + } |
|
192 | + } |
|
193 | + return $css; |
|
194 | + } |
|
195 | 195 | } |
@@ -18,158 +18,158 @@ |
||
18 | 18 | */ |
19 | 19 | final class Async { |
20 | 20 | |
21 | - /** |
|
22 | - * Only load the webfont script if this is true. |
|
23 | - * |
|
24 | - * @static |
|
25 | - * @access public |
|
26 | - * @since 1.0.0 |
|
27 | - * @var bool |
|
28 | - */ |
|
29 | - public static $load = false; |
|
30 | - |
|
31 | - /** |
|
32 | - * The config ID. |
|
33 | - * |
|
34 | - * @access protected |
|
35 | - * @since 1.0.0 |
|
36 | - * @var string |
|
37 | - */ |
|
38 | - protected $config_id; |
|
39 | - |
|
40 | - /** |
|
41 | - * The \Kirki\Module\Webfonts object. |
|
42 | - * |
|
43 | - * @access protected |
|
44 | - * @since 1.0.0 |
|
45 | - * @var object |
|
46 | - */ |
|
47 | - protected $webfonts; |
|
48 | - |
|
49 | - /** |
|
50 | - * The \Kirki\Module\Webfonts\Google object. |
|
51 | - * |
|
52 | - * @access protected |
|
53 | - * @since 1.0.0 |
|
54 | - * @var object |
|
55 | - */ |
|
56 | - protected $googlefonts; |
|
57 | - |
|
58 | - /** |
|
59 | - * Fonts to load. |
|
60 | - * |
|
61 | - * @access protected |
|
62 | - * @since 1.0.0 |
|
63 | - * @var array |
|
64 | - */ |
|
65 | - protected $fonts_to_load = []; |
|
66 | - |
|
67 | - /** |
|
68 | - * Constructor. |
|
69 | - * |
|
70 | - * @access public |
|
71 | - * @since 1.0.0 |
|
72 | - * @param string $config_id The config-ID. |
|
73 | - * @param object $webfonts The \Kirki\Module\Webfonts object. |
|
74 | - * @param object $googlefonts The \Kirki\Module\Webfonts\Google object. |
|
75 | - * @param array $args Extra args we want to pass. |
|
76 | - */ |
|
77 | - public function __construct( $config_id, $webfonts, $googlefonts, $args = [] ) { |
|
78 | - $this->config_id = $config_id; |
|
79 | - $this->webfonts = $webfonts; |
|
80 | - $this->googlefonts = $googlefonts; |
|
81 | - |
|
82 | - add_action( 'wp_head', [ $this, 'webfont_loader' ] ); |
|
83 | - add_action( 'wp_head', [ $this, 'webfont_loader_script' ], 30 ); |
|
84 | - |
|
85 | - // Add these in the dashboard to support editor-styles. |
|
86 | - add_action( 'admin_enqueue_scripts', [ $this, 'webfont_loader' ] ); |
|
87 | - add_action( 'admin_enqueue_scripts', [ $this, 'webfont_loader_script' ], 30 ); |
|
88 | - |
|
89 | - // add_filter( 'wp_resource_hints', [ $this, 'resource_hints' ], 10, 2 ); |
|
90 | - } |
|
91 | - |
|
92 | - /** |
|
93 | - * Add preconnect for Google Fonts. |
|
94 | - * |
|
95 | - * @access public |
|
96 | - * @param array $urls URLs to print for resource hints. |
|
97 | - * @param string $relation_type The relation type the URLs are printed. |
|
98 | - * @return array $urls URLs to print for resource hints. |
|
99 | - */ |
|
100 | - public function resource_hints( $urls, $relation_type ) { |
|
101 | - $fonts_to_load = $this->googlefonts->fonts; |
|
102 | - |
|
103 | - if ( ! empty( $fonts_to_load ) && 'preconnect' === $relation_type ) { |
|
104 | - $urls[] = [ |
|
105 | - 'href' => 'https://fonts.gstatic.com', |
|
106 | - 'crossorigin', |
|
107 | - ]; |
|
108 | - } |
|
109 | - return $urls; |
|
110 | - } |
|
111 | - |
|
112 | - /** |
|
113 | - * Webfont Loader for Google Fonts. |
|
114 | - * |
|
115 | - * @access public |
|
116 | - * @since 1.0.0 |
|
117 | - */ |
|
118 | - public function webfont_loader() { |
|
119 | - |
|
120 | - // Go through our fields and populate $this->fonts. |
|
121 | - $this->webfonts->loop_fields( $this->config_id ); |
|
122 | - |
|
123 | - $this->googlefonts->fonts = apply_filters( 'kirki_enqueue_google_fonts', $this->googlefonts->fonts ); |
|
124 | - |
|
125 | - // Goes through $this->fonts and adds or removes things as needed. |
|
126 | - $this->googlefonts->process_fonts(); |
|
127 | - |
|
128 | - foreach ( $this->googlefonts->fonts as $font => $weights ) { |
|
129 | - foreach ( $weights as $key => $value ) { |
|
130 | - if ( 'italic' === $value ) { |
|
131 | - $weights[ $key ] = '400i'; |
|
132 | - } else { |
|
133 | - $weights[ $key ] = str_replace( [ 'regular', 'bold', 'italic' ], [ '400', '', 'i' ], $value ); |
|
134 | - } |
|
135 | - } |
|
136 | - $this->fonts_to_load[] = $font . ':' . join( ',', $weights ) . ':cyrillic,cyrillic-ext,devanagari,greek,greek-ext,khmer,latin,latin-ext,vietnamese,hebrew,arabic,bengali,gujarati,tamil,telugu,thai'; |
|
137 | - } |
|
138 | - if ( ! empty( $this->fonts_to_load ) ) { |
|
139 | - self::$load = true; |
|
140 | - } |
|
141 | - |
|
142 | - global $wp_customize; |
|
143 | - if ( self::$load || $wp_customize || is_customize_preview() ) { |
|
144 | - wp_enqueue_script( 'webfont-loader', URL::get_from_path( dirname( __DIR__ ) . '/assets/scripts/vendor-typekit/webfontloader.js' ), [], '3.0.28', true ); |
|
145 | - } |
|
146 | - } |
|
147 | - |
|
148 | - /** |
|
149 | - * Webfont Loader script for Google Fonts. |
|
150 | - * |
|
151 | - * @access public |
|
152 | - * @since 1.0.0 |
|
153 | - */ |
|
154 | - public function webfont_loader_script() { |
|
155 | - if ( ! empty( $this->fonts_to_load ) ) { |
|
156 | - wp_add_inline_script( |
|
157 | - 'webfont-loader', |
|
158 | - 'WebFont.load({google:{families:[\'' . join( '\', \'', $this->fonts_to_load ) . '\']}});', |
|
159 | - 'after' |
|
160 | - ); |
|
161 | - } |
|
162 | - } |
|
163 | - |
|
164 | - /** |
|
165 | - * Set the $load property of this object. |
|
166 | - * |
|
167 | - * @access public |
|
168 | - * @since 1.0.0 |
|
169 | - * @param bool $load Set to false to disable loading. |
|
170 | - * @return void |
|
171 | - */ |
|
172 | - public function set_load( $load ) { |
|
173 | - self::$load = $load; |
|
174 | - } |
|
21 | + /** |
|
22 | + * Only load the webfont script if this is true. |
|
23 | + * |
|
24 | + * @static |
|
25 | + * @access public |
|
26 | + * @since 1.0.0 |
|
27 | + * @var bool |
|
28 | + */ |
|
29 | + public static $load = false; |
|
30 | + |
|
31 | + /** |
|
32 | + * The config ID. |
|
33 | + * |
|
34 | + * @access protected |
|
35 | + * @since 1.0.0 |
|
36 | + * @var string |
|
37 | + */ |
|
38 | + protected $config_id; |
|
39 | + |
|
40 | + /** |
|
41 | + * The \Kirki\Module\Webfonts object. |
|
42 | + * |
|
43 | + * @access protected |
|
44 | + * @since 1.0.0 |
|
45 | + * @var object |
|
46 | + */ |
|
47 | + protected $webfonts; |
|
48 | + |
|
49 | + /** |
|
50 | + * The \Kirki\Module\Webfonts\Google object. |
|
51 | + * |
|
52 | + * @access protected |
|
53 | + * @since 1.0.0 |
|
54 | + * @var object |
|
55 | + */ |
|
56 | + protected $googlefonts; |
|
57 | + |
|
58 | + /** |
|
59 | + * Fonts to load. |
|
60 | + * |
|
61 | + * @access protected |
|
62 | + * @since 1.0.0 |
|
63 | + * @var array |
|
64 | + */ |
|
65 | + protected $fonts_to_load = []; |
|
66 | + |
|
67 | + /** |
|
68 | + * Constructor. |
|
69 | + * |
|
70 | + * @access public |
|
71 | + * @since 1.0.0 |
|
72 | + * @param string $config_id The config-ID. |
|
73 | + * @param object $webfonts The \Kirki\Module\Webfonts object. |
|
74 | + * @param object $googlefonts The \Kirki\Module\Webfonts\Google object. |
|
75 | + * @param array $args Extra args we want to pass. |
|
76 | + */ |
|
77 | + public function __construct( $config_id, $webfonts, $googlefonts, $args = [] ) { |
|
78 | + $this->config_id = $config_id; |
|
79 | + $this->webfonts = $webfonts; |
|
80 | + $this->googlefonts = $googlefonts; |
|
81 | + |
|
82 | + add_action( 'wp_head', [ $this, 'webfont_loader' ] ); |
|
83 | + add_action( 'wp_head', [ $this, 'webfont_loader_script' ], 30 ); |
|
84 | + |
|
85 | + // Add these in the dashboard to support editor-styles. |
|
86 | + add_action( 'admin_enqueue_scripts', [ $this, 'webfont_loader' ] ); |
|
87 | + add_action( 'admin_enqueue_scripts', [ $this, 'webfont_loader_script' ], 30 ); |
|
88 | + |
|
89 | + // add_filter( 'wp_resource_hints', [ $this, 'resource_hints' ], 10, 2 ); |
|
90 | + } |
|
91 | + |
|
92 | + /** |
|
93 | + * Add preconnect for Google Fonts. |
|
94 | + * |
|
95 | + * @access public |
|
96 | + * @param array $urls URLs to print for resource hints. |
|
97 | + * @param string $relation_type The relation type the URLs are printed. |
|
98 | + * @return array $urls URLs to print for resource hints. |
|
99 | + */ |
|
100 | + public function resource_hints( $urls, $relation_type ) { |
|
101 | + $fonts_to_load = $this->googlefonts->fonts; |
|
102 | + |
|
103 | + if ( ! empty( $fonts_to_load ) && 'preconnect' === $relation_type ) { |
|
104 | + $urls[] = [ |
|
105 | + 'href' => 'https://fonts.gstatic.com', |
|
106 | + 'crossorigin', |
|
107 | + ]; |
|
108 | + } |
|
109 | + return $urls; |
|
110 | + } |
|
111 | + |
|
112 | + /** |
|
113 | + * Webfont Loader for Google Fonts. |
|
114 | + * |
|
115 | + * @access public |
|
116 | + * @since 1.0.0 |
|
117 | + */ |
|
118 | + public function webfont_loader() { |
|
119 | + |
|
120 | + // Go through our fields and populate $this->fonts. |
|
121 | + $this->webfonts->loop_fields( $this->config_id ); |
|
122 | + |
|
123 | + $this->googlefonts->fonts = apply_filters( 'kirki_enqueue_google_fonts', $this->googlefonts->fonts ); |
|
124 | + |
|
125 | + // Goes through $this->fonts and adds or removes things as needed. |
|
126 | + $this->googlefonts->process_fonts(); |
|
127 | + |
|
128 | + foreach ( $this->googlefonts->fonts as $font => $weights ) { |
|
129 | + foreach ( $weights as $key => $value ) { |
|
130 | + if ( 'italic' === $value ) { |
|
131 | + $weights[ $key ] = '400i'; |
|
132 | + } else { |
|
133 | + $weights[ $key ] = str_replace( [ 'regular', 'bold', 'italic' ], [ '400', '', 'i' ], $value ); |
|
134 | + } |
|
135 | + } |
|
136 | + $this->fonts_to_load[] = $font . ':' . join( ',', $weights ) . ':cyrillic,cyrillic-ext,devanagari,greek,greek-ext,khmer,latin,latin-ext,vietnamese,hebrew,arabic,bengali,gujarati,tamil,telugu,thai'; |
|
137 | + } |
|
138 | + if ( ! empty( $this->fonts_to_load ) ) { |
|
139 | + self::$load = true; |
|
140 | + } |
|
141 | + |
|
142 | + global $wp_customize; |
|
143 | + if ( self::$load || $wp_customize || is_customize_preview() ) { |
|
144 | + wp_enqueue_script( 'webfont-loader', URL::get_from_path( dirname( __DIR__ ) . '/assets/scripts/vendor-typekit/webfontloader.js' ), [], '3.0.28', true ); |
|
145 | + } |
|
146 | + } |
|
147 | + |
|
148 | + /** |
|
149 | + * Webfont Loader script for Google Fonts. |
|
150 | + * |
|
151 | + * @access public |
|
152 | + * @since 1.0.0 |
|
153 | + */ |
|
154 | + public function webfont_loader_script() { |
|
155 | + if ( ! empty( $this->fonts_to_load ) ) { |
|
156 | + wp_add_inline_script( |
|
157 | + 'webfont-loader', |
|
158 | + 'WebFont.load({google:{families:[\'' . join( '\', \'', $this->fonts_to_load ) . '\']}});', |
|
159 | + 'after' |
|
160 | + ); |
|
161 | + } |
|
162 | + } |
|
163 | + |
|
164 | + /** |
|
165 | + * Set the $load property of this object. |
|
166 | + * |
|
167 | + * @access public |
|
168 | + * @since 1.0.0 |
|
169 | + * @param bool $load Set to false to disable loading. |
|
170 | + * @return void |
|
171 | + */ |
|
172 | + public function set_load( $load ) { |
|
173 | + self::$load = $load; |
|
174 | + } |
|
175 | 175 | } |
@@ -20,224 +20,224 @@ |
||
20 | 20 | */ |
21 | 21 | final class Google { |
22 | 22 | |
23 | - /** |
|
24 | - * The object instance. |
|
25 | - * We use the singleton pattern here to avoid loading the google-font array multiple times. |
|
26 | - * This is mostly a performance tweak. |
|
27 | - * |
|
28 | - * @access private |
|
29 | - * @var null|object |
|
30 | - */ |
|
31 | - private static $instance = null; |
|
32 | - |
|
33 | - /** |
|
34 | - * DUMMY. DOESN'T DO ANYTHING, SIMPLY BACKWARDS-COMPATIBILITY. |
|
35 | - * |
|
36 | - * @static |
|
37 | - * @access public |
|
38 | - * @var bool |
|
39 | - */ |
|
40 | - public static $force_load_all_subsets = false; |
|
41 | - |
|
42 | - /** |
|
43 | - * If set to true, forces loading ALL variants. |
|
44 | - * |
|
45 | - * @static |
|
46 | - * @access public |
|
47 | - * @var bool |
|
48 | - */ |
|
49 | - public static $force_load_all_variants = false; |
|
50 | - |
|
51 | - /** |
|
52 | - * The array of fonts |
|
53 | - * |
|
54 | - * @access public |
|
55 | - * @var array |
|
56 | - */ |
|
57 | - public $fonts = []; |
|
58 | - |
|
59 | - /** |
|
60 | - * An array of all google fonts. |
|
61 | - * |
|
62 | - * @access private |
|
63 | - * @var array |
|
64 | - */ |
|
65 | - private $google_fonts = []; |
|
66 | - |
|
67 | - /** |
|
68 | - * An array of fonts that should be hosted locally instead of served via the google-CDN. |
|
69 | - * |
|
70 | - * @access protected |
|
71 | - * @since 1.0.0 |
|
72 | - * @var array |
|
73 | - */ |
|
74 | - protected $hosted_fonts = []; |
|
75 | - |
|
76 | - /** |
|
77 | - * The class constructor. |
|
78 | - */ |
|
79 | - private function __construct() { |
|
80 | - $config = apply_filters( 'kirki_config', [] ); |
|
81 | - |
|
82 | - // If we have set $config['disable_google_fonts'] to true then do not proceed any further. |
|
83 | - if ( isset( $config['disable_google_fonts'] ) && true === $config['disable_google_fonts'] ) { |
|
84 | - return; |
|
85 | - } |
|
86 | - |
|
87 | - new GoogleFonts(); |
|
88 | - add_action( 'wp_ajax_kirki_fonts_standard_all_get', [ $this, 'get_standardfonts_json' ] ); |
|
89 | - add_action( 'wp_ajax_nopriv_kirki_fonts_standard_all_get', [ $this, 'get_standardfonts_json' ] ); |
|
90 | - |
|
91 | - // Populate the array of google fonts. |
|
92 | - $this->google_fonts = Fonts::get_google_fonts(); |
|
93 | - } |
|
94 | - |
|
95 | - /** |
|
96 | - * Get the one, true instance of this class. |
|
97 | - * Prevents performance issues since this is only loaded once. |
|
98 | - * |
|
99 | - * @return object Google |
|
100 | - */ |
|
101 | - public static function get_instance() { |
|
102 | - if ( null === self::$instance ) { |
|
103 | - self::$instance = new self(); |
|
104 | - } |
|
105 | - return self::$instance; |
|
106 | - } |
|
107 | - |
|
108 | - /** |
|
109 | - * Processes the arguments of a field |
|
110 | - * determines if it's a typography field |
|
111 | - * and if it is, then takes appropriate actions. |
|
112 | - * |
|
113 | - * @param array $args The field arguments. |
|
114 | - */ |
|
115 | - public function generate_google_font( $args ) { |
|
116 | - |
|
117 | - // Process typography fields. |
|
118 | - $process = ( ( isset( $args['type'] ) && 'kirki-typography' === $args['type'] ) || ( isset( $args['choices'] ) && isset( $args['choices']['parent_type'] ) && 'kirki-typography' === $args['choices']['parent_type'] ) ); |
|
119 | - if ( apply_filters( 'kirki_generate_google_font', $process, $args ) ) { |
|
120 | - |
|
121 | - // Get the value. |
|
122 | - $option_type = ( isset( $args['option_type'] ) ) ? $args['option_type'] : 'theme_mod'; |
|
123 | - $default = ( isset( $args['default'] ) ) ? $args['default'] : ''; |
|
124 | - $value = apply_filters( 'kirki_get_value', get_theme_mod( $args['settings'], $default ), $args['settings'], $default, $option_type ); |
|
125 | - |
|
126 | - // If we don't have a font-family then we can skip this. |
|
127 | - if ( ! isset( $value['font-family'] ) || in_array( $value['font-family'], $this->hosted_fonts, true ) ) { |
|
128 | - return; |
|
129 | - } |
|
130 | - |
|
131 | - // If not a google-font, then we can skip this. |
|
132 | - if ( ! isset( $value['font-family'] ) || ! Fonts::is_google_font( $value['font-family'] ) ) { |
|
133 | - return; |
|
134 | - } |
|
135 | - |
|
136 | - // Set a default value for variants. |
|
137 | - if ( ! isset( $value['variant'] ) ) { |
|
138 | - $value['variant'] = 'regular'; |
|
139 | - } |
|
140 | - |
|
141 | - // Add the requested google-font. |
|
142 | - if ( ! is_array( $value ) || ! isset( $value['font-family'] ) || ! isset( $this->fonts[ $value['font-family'] ] ) ) { |
|
143 | - $this->fonts[ $value['font-family'] ] = []; |
|
144 | - } |
|
145 | - if ( ! in_array( $value['variant'], $this->fonts[ $value['font-family'] ], true ) ) { |
|
146 | - $this->fonts[ $value['font-family'] ][] = $value['variant']; |
|
147 | - } |
|
148 | - |
|
149 | - // Are we force-loading all variants? |
|
150 | - if ( true === self::$force_load_all_variants ) { |
|
151 | - $all_variants = Fonts::get_all_variants(); |
|
152 | - $args['choices']['variant'] = array_keys( $all_variants ); |
|
153 | - } |
|
154 | - |
|
155 | - if ( ! empty( $args['choices']['variant'] ) && is_array( $args['choices']['variant'] ) ) { |
|
156 | - foreach ( $args['choices']['variant'] as $extra_variant ) { |
|
157 | - $this->fonts[ $value['font-family'] ][] = $extra_variant; |
|
158 | - } |
|
159 | - } |
|
160 | - return; |
|
161 | - } |
|
162 | - |
|
163 | - // Process non-typography fields. |
|
164 | - if ( isset( $args['output'] ) && is_array( $args['output'] ) ) { |
|
165 | - foreach ( $args['output'] as $output ) { |
|
166 | - |
|
167 | - // If we don't have a typography-related output argument we can skip this. |
|
168 | - if ( ! isset( $output['property'] ) || ! in_array( $output['property'], [ 'font-family', 'font-weight' ], true ) ) { |
|
169 | - continue; |
|
170 | - } |
|
171 | - |
|
172 | - // Get the value. |
|
173 | - $option_type = ( isset( $args['option_type'] ) ) ? $args['option_type'] : 'theme_mod'; |
|
174 | - $default = ( isset( $args['default'] ) ) ? $args['default'] : ''; |
|
175 | - $value = apply_filters( 'kirki_get_value', get_theme_mod( $args['settings'], $default ), $args['settings'], $default, $option_type ); |
|
176 | - |
|
177 | - if ( is_string( $value ) ) { |
|
178 | - if ( 'font-family' === $output['property'] ) { |
|
179 | - if ( ! array_key_exists( $value, $this->fonts ) ) { |
|
180 | - $this->fonts[ $value ] = []; |
|
181 | - } |
|
182 | - } elseif ( 'font-weight' === $output['property'] ) { |
|
183 | - foreach ( $this->fonts as $font => $variants ) { |
|
184 | - if ( ! in_array( $value, $variants, true ) ) { |
|
185 | - $this->fonts[ $font ][] = $value; |
|
186 | - } |
|
187 | - } |
|
188 | - } |
|
189 | - } |
|
190 | - } |
|
191 | - } |
|
192 | - } |
|
193 | - |
|
194 | - /** |
|
195 | - * Determines the vbalidity of the selected font as well as its properties. |
|
196 | - * This is vital to make sure that the google-font script that we'll generate later |
|
197 | - * does not contain any invalid options. |
|
198 | - */ |
|
199 | - public function process_fonts() { |
|
200 | - |
|
201 | - // Early exit if font-family is empty. |
|
202 | - if ( empty( $this->fonts ) ) { |
|
203 | - return; |
|
204 | - } |
|
205 | - |
|
206 | - foreach ( $this->fonts as $font => $variants ) { |
|
207 | - |
|
208 | - // Determine if this is indeed a google font or not. |
|
209 | - // If it's not, then just remove it from the array. |
|
210 | - if ( ! array_key_exists( $font, $this->google_fonts ) ) { |
|
211 | - unset( $this->fonts[ $font ] ); |
|
212 | - continue; |
|
213 | - } |
|
214 | - |
|
215 | - // Get all valid font variants for this font. |
|
216 | - $font_variants = []; |
|
217 | - if ( isset( $this->google_fonts[ $font ]['variants'] ) ) { |
|
218 | - $font_variants = $this->google_fonts[ $font ]['variants']; |
|
219 | - } |
|
220 | - foreach ( $variants as $variant ) { |
|
221 | - |
|
222 | - // If this is not a valid variant for this font-family |
|
223 | - // then unset it and move on to the next one. |
|
224 | - if ( ! in_array( strval( $variant ), $font_variants, true ) ) { |
|
225 | - $variant_key = array_search( $variant, $this->fonts[ $font ], true ); |
|
226 | - unset( $this->fonts[ $font ][ $variant_key ] ); |
|
227 | - continue; |
|
228 | - } |
|
229 | - } |
|
230 | - } |
|
231 | - } |
|
232 | - |
|
233 | - /** |
|
234 | - * Get the standard fonts JSON. |
|
235 | - * |
|
236 | - * @since 1.0.0 |
|
237 | - * @return void |
|
238 | - */ |
|
239 | - public function get_standardfonts_json() { |
|
240 | - echo wp_json_encode( Fonts::get_standard_fonts() ); |
|
241 | - wp_die(); |
|
242 | - } |
|
23 | + /** |
|
24 | + * The object instance. |
|
25 | + * We use the singleton pattern here to avoid loading the google-font array multiple times. |
|
26 | + * This is mostly a performance tweak. |
|
27 | + * |
|
28 | + * @access private |
|
29 | + * @var null|object |
|
30 | + */ |
|
31 | + private static $instance = null; |
|
32 | + |
|
33 | + /** |
|
34 | + * DUMMY. DOESN'T DO ANYTHING, SIMPLY BACKWARDS-COMPATIBILITY. |
|
35 | + * |
|
36 | + * @static |
|
37 | + * @access public |
|
38 | + * @var bool |
|
39 | + */ |
|
40 | + public static $force_load_all_subsets = false; |
|
41 | + |
|
42 | + /** |
|
43 | + * If set to true, forces loading ALL variants. |
|
44 | + * |
|
45 | + * @static |
|
46 | + * @access public |
|
47 | + * @var bool |
|
48 | + */ |
|
49 | + public static $force_load_all_variants = false; |
|
50 | + |
|
51 | + /** |
|
52 | + * The array of fonts |
|
53 | + * |
|
54 | + * @access public |
|
55 | + * @var array |
|
56 | + */ |
|
57 | + public $fonts = []; |
|
58 | + |
|
59 | + /** |
|
60 | + * An array of all google fonts. |
|
61 | + * |
|
62 | + * @access private |
|
63 | + * @var array |
|
64 | + */ |
|
65 | + private $google_fonts = []; |
|
66 | + |
|
67 | + /** |
|
68 | + * An array of fonts that should be hosted locally instead of served via the google-CDN. |
|
69 | + * |
|
70 | + * @access protected |
|
71 | + * @since 1.0.0 |
|
72 | + * @var array |
|
73 | + */ |
|
74 | + protected $hosted_fonts = []; |
|
75 | + |
|
76 | + /** |
|
77 | + * The class constructor. |
|
78 | + */ |
|
79 | + private function __construct() { |
|
80 | + $config = apply_filters( 'kirki_config', [] ); |
|
81 | + |
|
82 | + // If we have set $config['disable_google_fonts'] to true then do not proceed any further. |
|
83 | + if ( isset( $config['disable_google_fonts'] ) && true === $config['disable_google_fonts'] ) { |
|
84 | + return; |
|
85 | + } |
|
86 | + |
|
87 | + new GoogleFonts(); |
|
88 | + add_action( 'wp_ajax_kirki_fonts_standard_all_get', [ $this, 'get_standardfonts_json' ] ); |
|
89 | + add_action( 'wp_ajax_nopriv_kirki_fonts_standard_all_get', [ $this, 'get_standardfonts_json' ] ); |
|
90 | + |
|
91 | + // Populate the array of google fonts. |
|
92 | + $this->google_fonts = Fonts::get_google_fonts(); |
|
93 | + } |
|
94 | + |
|
95 | + /** |
|
96 | + * Get the one, true instance of this class. |
|
97 | + * Prevents performance issues since this is only loaded once. |
|
98 | + * |
|
99 | + * @return object Google |
|
100 | + */ |
|
101 | + public static function get_instance() { |
|
102 | + if ( null === self::$instance ) { |
|
103 | + self::$instance = new self(); |
|
104 | + } |
|
105 | + return self::$instance; |
|
106 | + } |
|
107 | + |
|
108 | + /** |
|
109 | + * Processes the arguments of a field |
|
110 | + * determines if it's a typography field |
|
111 | + * and if it is, then takes appropriate actions. |
|
112 | + * |
|
113 | + * @param array $args The field arguments. |
|
114 | + */ |
|
115 | + public function generate_google_font( $args ) { |
|
116 | + |
|
117 | + // Process typography fields. |
|
118 | + $process = ( ( isset( $args['type'] ) && 'kirki-typography' === $args['type'] ) || ( isset( $args['choices'] ) && isset( $args['choices']['parent_type'] ) && 'kirki-typography' === $args['choices']['parent_type'] ) ); |
|
119 | + if ( apply_filters( 'kirki_generate_google_font', $process, $args ) ) { |
|
120 | + |
|
121 | + // Get the value. |
|
122 | + $option_type = ( isset( $args['option_type'] ) ) ? $args['option_type'] : 'theme_mod'; |
|
123 | + $default = ( isset( $args['default'] ) ) ? $args['default'] : ''; |
|
124 | + $value = apply_filters( 'kirki_get_value', get_theme_mod( $args['settings'], $default ), $args['settings'], $default, $option_type ); |
|
125 | + |
|
126 | + // If we don't have a font-family then we can skip this. |
|
127 | + if ( ! isset( $value['font-family'] ) || in_array( $value['font-family'], $this->hosted_fonts, true ) ) { |
|
128 | + return; |
|
129 | + } |
|
130 | + |
|
131 | + // If not a google-font, then we can skip this. |
|
132 | + if ( ! isset( $value['font-family'] ) || ! Fonts::is_google_font( $value['font-family'] ) ) { |
|
133 | + return; |
|
134 | + } |
|
135 | + |
|
136 | + // Set a default value for variants. |
|
137 | + if ( ! isset( $value['variant'] ) ) { |
|
138 | + $value['variant'] = 'regular'; |
|
139 | + } |
|
140 | + |
|
141 | + // Add the requested google-font. |
|
142 | + if ( ! is_array( $value ) || ! isset( $value['font-family'] ) || ! isset( $this->fonts[ $value['font-family'] ] ) ) { |
|
143 | + $this->fonts[ $value['font-family'] ] = []; |
|
144 | + } |
|
145 | + if ( ! in_array( $value['variant'], $this->fonts[ $value['font-family'] ], true ) ) { |
|
146 | + $this->fonts[ $value['font-family'] ][] = $value['variant']; |
|
147 | + } |
|
148 | + |
|
149 | + // Are we force-loading all variants? |
|
150 | + if ( true === self::$force_load_all_variants ) { |
|
151 | + $all_variants = Fonts::get_all_variants(); |
|
152 | + $args['choices']['variant'] = array_keys( $all_variants ); |
|
153 | + } |
|
154 | + |
|
155 | + if ( ! empty( $args['choices']['variant'] ) && is_array( $args['choices']['variant'] ) ) { |
|
156 | + foreach ( $args['choices']['variant'] as $extra_variant ) { |
|
157 | + $this->fonts[ $value['font-family'] ][] = $extra_variant; |
|
158 | + } |
|
159 | + } |
|
160 | + return; |
|
161 | + } |
|
162 | + |
|
163 | + // Process non-typography fields. |
|
164 | + if ( isset( $args['output'] ) && is_array( $args['output'] ) ) { |
|
165 | + foreach ( $args['output'] as $output ) { |
|
166 | + |
|
167 | + // If we don't have a typography-related output argument we can skip this. |
|
168 | + if ( ! isset( $output['property'] ) || ! in_array( $output['property'], [ 'font-family', 'font-weight' ], true ) ) { |
|
169 | + continue; |
|
170 | + } |
|
171 | + |
|
172 | + // Get the value. |
|
173 | + $option_type = ( isset( $args['option_type'] ) ) ? $args['option_type'] : 'theme_mod'; |
|
174 | + $default = ( isset( $args['default'] ) ) ? $args['default'] : ''; |
|
175 | + $value = apply_filters( 'kirki_get_value', get_theme_mod( $args['settings'], $default ), $args['settings'], $default, $option_type ); |
|
176 | + |
|
177 | + if ( is_string( $value ) ) { |
|
178 | + if ( 'font-family' === $output['property'] ) { |
|
179 | + if ( ! array_key_exists( $value, $this->fonts ) ) { |
|
180 | + $this->fonts[ $value ] = []; |
|
181 | + } |
|
182 | + } elseif ( 'font-weight' === $output['property'] ) { |
|
183 | + foreach ( $this->fonts as $font => $variants ) { |
|
184 | + if ( ! in_array( $value, $variants, true ) ) { |
|
185 | + $this->fonts[ $font ][] = $value; |
|
186 | + } |
|
187 | + } |
|
188 | + } |
|
189 | + } |
|
190 | + } |
|
191 | + } |
|
192 | + } |
|
193 | + |
|
194 | + /** |
|
195 | + * Determines the vbalidity of the selected font as well as its properties. |
|
196 | + * This is vital to make sure that the google-font script that we'll generate later |
|
197 | + * does not contain any invalid options. |
|
198 | + */ |
|
199 | + public function process_fonts() { |
|
200 | + |
|
201 | + // Early exit if font-family is empty. |
|
202 | + if ( empty( $this->fonts ) ) { |
|
203 | + return; |
|
204 | + } |
|
205 | + |
|
206 | + foreach ( $this->fonts as $font => $variants ) { |
|
207 | + |
|
208 | + // Determine if this is indeed a google font or not. |
|
209 | + // If it's not, then just remove it from the array. |
|
210 | + if ( ! array_key_exists( $font, $this->google_fonts ) ) { |
|
211 | + unset( $this->fonts[ $font ] ); |
|
212 | + continue; |
|
213 | + } |
|
214 | + |
|
215 | + // Get all valid font variants for this font. |
|
216 | + $font_variants = []; |
|
217 | + if ( isset( $this->google_fonts[ $font ]['variants'] ) ) { |
|
218 | + $font_variants = $this->google_fonts[ $font ]['variants']; |
|
219 | + } |
|
220 | + foreach ( $variants as $variant ) { |
|
221 | + |
|
222 | + // If this is not a valid variant for this font-family |
|
223 | + // then unset it and move on to the next one. |
|
224 | + if ( ! in_array( strval( $variant ), $font_variants, true ) ) { |
|
225 | + $variant_key = array_search( $variant, $this->fonts[ $font ], true ); |
|
226 | + unset( $this->fonts[ $font ][ $variant_key ] ); |
|
227 | + continue; |
|
228 | + } |
|
229 | + } |
|
230 | + } |
|
231 | + } |
|
232 | + |
|
233 | + /** |
|
234 | + * Get the standard fonts JSON. |
|
235 | + * |
|
236 | + * @since 1.0.0 |
|
237 | + * @return void |
|
238 | + */ |
|
239 | + public function get_standardfonts_json() { |
|
240 | + echo wp_json_encode( Fonts::get_standard_fonts() ); |
|
241 | + wp_die(); |
|
242 | + } |
|
243 | 243 | } |
@@ -20,279 +20,279 @@ |
||
20 | 20 | */ |
21 | 21 | class ReactColorful extends Field { |
22 | 22 | |
23 | - /** |
|
24 | - * The field type. |
|
25 | - * |
|
26 | - * @access public |
|
27 | - * @since 1.0 |
|
28 | - * @var string |
|
29 | - */ |
|
30 | - public $type = 'kirki-react-colorful'; |
|
31 | - |
|
32 | - /** |
|
33 | - * The control class-name. |
|
34 | - * |
|
35 | - * @access protected |
|
36 | - * @since 0.1 |
|
37 | - * @var string |
|
38 | - */ |
|
39 | - protected $control_class = '\Kirki\Control\ReactColorful'; |
|
40 | - |
|
41 | - /** |
|
42 | - * Whether we should register the control class for JS-templating or not. |
|
43 | - * |
|
44 | - * @access protected |
|
45 | - * @since 0.1 |
|
46 | - * @var bool |
|
47 | - */ |
|
48 | - protected $control_has_js_template = true; |
|
49 | - |
|
50 | - /** |
|
51 | - * Additional logic for the field. |
|
52 | - * |
|
53 | - * @since 4.0.0 |
|
54 | - * @access protected |
|
55 | - * |
|
56 | - * @param array $args The field arguments. |
|
57 | - */ |
|
58 | - protected function init( $args ) { |
|
59 | - |
|
60 | - add_action( 'customize_preview_init', [ $this, 'enqueue_customize_preview_scripts' ] ); |
|
61 | - add_filter( 'kirki_output_control_classnames', [ $this, 'output_control_classnames' ] ); |
|
62 | - |
|
63 | - } |
|
64 | - |
|
65 | - /** |
|
66 | - * Filter arguments before creating the setting. |
|
67 | - * |
|
68 | - * @access public |
|
69 | - * @since 0.1 |
|
70 | - * @param array $args The field arguments. |
|
71 | - * @param WP_Customize_Manager $wp_customize The customizer instance. |
|
72 | - * @return array |
|
73 | - */ |
|
74 | - public function filter_setting_args( $args, $wp_customize ) { |
|
75 | - |
|
76 | - if ( $args['settings'] === $this->args['settings'] ) { |
|
77 | - $args = parent::filter_setting_args( $args, $wp_customize ); |
|
78 | - |
|
79 | - // Set the sanitize-callback if none is defined. |
|
80 | - if ( ! isset( $args['sanitize_callback'] ) || ! $args['sanitize_callback'] ) { |
|
81 | - $args['sanitize_callback'] = [ __CLASS__, 'sanitize' ]; |
|
82 | - |
|
83 | - // If this is a hue control then its value should be an integer. |
|
84 | - if ( isset( $args['mode'] ) && 'hue' === $args['mode'] ) { |
|
85 | - $args['sanitize_callback'] = 'absint'; |
|
86 | - } |
|
87 | - } |
|
88 | - |
|
89 | - // For postMessage/preview purpose, if property is not set, then set it to 'color'. |
|
90 | - if ( isset( $args['output'] ) && ! empty( $args['output'] ) && is_array( $args['output'] ) && ! isset( $args['output']['element'] ) ) { |
|
91 | - foreach ( $args['output'] as $index => $output ) { |
|
92 | - if ( ! isset( $output['property'] ) ) { |
|
93 | - if ( empty( $args['output'][ $index ] ) ) { |
|
94 | - $args['output'][ $index ] = []; |
|
95 | - } |
|
96 | - |
|
97 | - $args['output'][ $index ]['property'] = 'color'; |
|
98 | - } |
|
99 | - } |
|
100 | - } |
|
101 | - } |
|
102 | - |
|
103 | - return $args; |
|
104 | - |
|
105 | - } |
|
106 | - |
|
107 | - /** |
|
108 | - * Filter arguments before creating the control. |
|
109 | - * |
|
110 | - * @access public |
|
111 | - * @since 0.1 |
|
112 | - * @param array $args The field arguments. |
|
113 | - * @param WP_Customize_Manager $wp_customize The customizer instance. |
|
114 | - * @return array |
|
115 | - */ |
|
116 | - public function filter_control_args( $args, $wp_customize ) { |
|
117 | - |
|
118 | - if ( $args['settings'] === $this->args['settings'] ) { |
|
119 | - $args = parent::filter_control_args( $args, $wp_customize ); |
|
120 | - $args['type'] = 'kirki-react-colorful'; |
|
121 | - } |
|
122 | - |
|
123 | - return $args; |
|
124 | - |
|
125 | - } |
|
126 | - |
|
127 | - /** |
|
128 | - * Sanitize colors. |
|
129 | - * |
|
130 | - * @static |
|
131 | - * @access public |
|
132 | - * @since 1.0 |
|
133 | - * |
|
134 | - * @param string|array $value The color. |
|
135 | - * @return string|array |
|
136 | - */ |
|
137 | - public static function sanitize( $value ) { |
|
138 | - |
|
139 | - $sanitized_value = ''; |
|
140 | - |
|
141 | - if ( is_string( $value ) ) { |
|
142 | - $sanitized_value = self::sanitize_color_string( $value ); |
|
143 | - } elseif ( is_array( $value ) ) { |
|
144 | - if ( isset( $value['r'] ) || isset( $value['g'] ) || isset( $value['b'] ) ) { |
|
145 | - $sanitized_value = self::sanitize_color_array( $value, 'rgb' ); |
|
146 | - } elseif ( isset( $value['h'] ) || isset( $value['s'] ) ) { |
|
147 | - if ( isset( $value['l'] ) ) { |
|
148 | - $sanitized_value = self::sanitize_color_array( $value, 'hsl' ); |
|
149 | - } elseif ( isset( $value['v'] ) ) { |
|
150 | - $sanitized_value = self::sanitize_color_array( $value, 'hsv' ); |
|
151 | - } |
|
152 | - } |
|
153 | - } |
|
154 | - |
|
155 | - return $sanitized_value; |
|
156 | - |
|
157 | - } |
|
158 | - |
|
159 | - /** |
|
160 | - * Sanitize single color array. |
|
161 | - * |
|
162 | - * @param array $color The provided color in array format. |
|
163 | - * @param string $color_type The color type. Accepts: rgb, hsl, and hsv. |
|
164 | - * |
|
165 | - * @return array The sanitized color. |
|
166 | - */ |
|
167 | - public static function sanitize_color_array( $color, $color_type = 'rgb' ) { |
|
168 | - |
|
169 | - $keys = [ 'r', 'g', 'b' ]; |
|
170 | - $mins = [ 0, 0, 0 ]; |
|
171 | - $maxs = [ 255, 255, 255 ]; |
|
172 | - |
|
173 | - if ( 'hsl' === $color_type || 'hsv' === $color_type ) { |
|
174 | - $keys = [ 'h', 's', '' ]; |
|
175 | - $keys[2] = isset( $color['v'] ) ? 'v' : 'l'; |
|
176 | - |
|
177 | - $mins = [ 0, 0, 0 ]; |
|
178 | - $maxs = [ 360, 100, 100 ]; |
|
179 | - } |
|
180 | - |
|
181 | - $sanitized_color = []; |
|
182 | - |
|
183 | - $sanitized_color = [ |
|
184 | - $keys[0] => isset( $color[ $keys[0] ] ) ? absint( $color[ $keys[0] ] ) : $mins[0], |
|
185 | - $keys[1] => isset( $color[ $keys[1] ] ) ? absint( $color[ $keys[1] ] ) : $mins[1], |
|
186 | - $keys[2] => isset( $color[ $keys[2] ] ) ? absint( $color[ $keys[2] ] ) : $mins[2], |
|
187 | - ]; |
|
188 | - |
|
189 | - $sanitized_color[ $keys[0] ] = $sanitized_color[ $keys[0] ] < $mins[0] ? $mins[0] : $sanitized_color[ $keys[0] ]; |
|
190 | - $sanitized_color[ $keys[0] ] = $sanitized_color[ $keys[0] ] > $maxs[0] ? $maxs[0] : $sanitized_color[ $keys[0] ]; |
|
191 | - |
|
192 | - $sanitized_color[ $keys[1] ] = $sanitized_color[ $keys[1] ] < $mins[1] ? $mins[1] : $sanitized_color[ $keys[1] ]; |
|
193 | - $sanitized_color[ $keys[1] ] = $sanitized_color[ $keys[1] ] > $maxs[1] ? $maxs[1] : $sanitized_color[ $keys[1] ]; |
|
194 | - |
|
195 | - $sanitized_color[ $keys[2] ] = $sanitized_color[ $keys[2] ] < $mins[2] ? $mins[2] : $sanitized_color[ $keys[2] ]; |
|
196 | - $sanitized_color[ $keys[2] ] = $sanitized_color[ $keys[2] ] > $maxs[2] ? $maxs[2] : $sanitized_color[ $keys[2] ]; |
|
197 | - |
|
198 | - if ( isset( $color['a'] ) ) { |
|
199 | - $sanitized_color['a'] = isset( $color['a'] ) ? filter_var( $color['a'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION ) : 1; |
|
200 | - $sanitized_color['a'] = $sanitized_color['a'] < 0 ? 0 : $sanitized_color['a']; |
|
201 | - $sanitized_color['a'] = $sanitized_color['a'] > 1 ? 1 : $sanitized_color['a']; |
|
202 | - } |
|
203 | - |
|
204 | - return $sanitized_color; |
|
205 | - |
|
206 | - } |
|
207 | - |
|
208 | - /** |
|
209 | - * Sanitize color string. |
|
210 | - * |
|
211 | - * @static |
|
212 | - * @access public |
|
213 | - * @since 1.0 |
|
214 | - * |
|
215 | - * @param string $value The color. |
|
216 | - * @return string |
|
217 | - */ |
|
218 | - public static function sanitize_color_string( $value ) { |
|
219 | - |
|
220 | - $value = strtolower( $value ); |
|
221 | - |
|
222 | - /** |
|
223 | - * This pattern will check and match 3/6/8-character hex, rgb, rgba, hsl, hsla, hsv, and hsva colors. |
|
224 | - * |
|
225 | - * RGB regex: |
|
226 | - * |
|
227 | - * @link https://stackoverflow.com/questions/9585973/javascript-regular-expression-for-rgb-values#answer-9586045 |
|
228 | - * |
|
229 | - * For testing it, you can use these links: |
|
230 | - * |
|
231 | - * @link https://regex101.com/ |
|
232 | - * @link https://regexr.com/ |
|
233 | - * @link https://www.regextester.com/ |
|
234 | - * |
|
235 | - * How to test it? |
|
236 | - * |
|
237 | - * Paste the following code to the test field (of course without the asterisks and spaces in front of them): |
|
238 | - * rgba(255, 255, 0, 0.9) |
|
239 | - * rgb(255, 255, 0) |
|
240 | - * #ff0 |
|
241 | - * #ffff00 |
|
242 | - * hsl(150, 25%, 25%) |
|
243 | - * hsla(250, 25%, 25%, 0.7) |
|
244 | - * hsv(125, 15%, 30%) |
|
245 | - * hsva(125, 15%, 30%, 0.5) |
|
246 | - * |
|
247 | - * And then paste the regex `$pattern` below (without the single quote's start and end) to the regular expression box. |
|
248 | - * Set the flag to use "global" and "multiline". |
|
249 | - */ |
|
250 | - $pattern = '/^(\#[\da-f]{3}|\#[\da-f]{6}|\#[\da-f]{8}|rgba\(((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*,\s*){2}((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*)(,\s*(0\.\d+|1))\)|rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)|hsla\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)(,\s*(0\.\d+|1))\)|hsl\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)\)|hsva\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)(,\s*(0\.\d+|1))\)|hsv\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)\))$/'; |
|
251 | - |
|
252 | - preg_match( $pattern, $value, $matches ); |
|
253 | - |
|
254 | - // Return the 1st match found. |
|
255 | - if ( isset( $matches[0] ) ) { |
|
256 | - if ( is_string( $matches[0] ) ) { |
|
257 | - return $matches[0]; |
|
258 | - } |
|
259 | - |
|
260 | - if ( is_array( $matches[0] ) && isset( $matches[0][0] ) ) { |
|
261 | - return $matches[0][0]; |
|
262 | - } |
|
263 | - } |
|
264 | - |
|
265 | - // If no match was found, return an empty string. |
|
266 | - return ''; |
|
267 | - } |
|
268 | - |
|
269 | - /** |
|
270 | - * Enqueue styles & scripts on 'customize_preview_init' action. |
|
271 | - * |
|
272 | - * @since 4.0.0 |
|
273 | - * @access public |
|
274 | - */ |
|
275 | - public function enqueue_customize_preview_scripts() { |
|
276 | - |
|
277 | - wp_enqueue_script( 'kirki-react-colorful', URL::get_from_path( dirname( dirname( __DIR__ ) ) ) . '/dist/preview.js', [ 'wp-hooks', 'customize-preview' ], $this->control_class::$control_ver, true ); |
|
278 | - |
|
279 | - } |
|
280 | - |
|
281 | - /** |
|
282 | - * Add output control class for react colorful control. |
|
283 | - * |
|
284 | - * @since 4.0.0 |
|
285 | - * @access public |
|
286 | - * |
|
287 | - * @param array $control_classes The existing control classes. |
|
288 | - * @return array |
|
289 | - */ |
|
290 | - public function output_control_classnames( $control_classes ) { |
|
291 | - |
|
292 | - $control_classes['kirki-react-colorful'] = '\Kirki\Field\CSS\ReactColorful'; |
|
293 | - |
|
294 | - return $control_classes; |
|
295 | - |
|
296 | - } |
|
23 | + /** |
|
24 | + * The field type. |
|
25 | + * |
|
26 | + * @access public |
|
27 | + * @since 1.0 |
|
28 | + * @var string |
|
29 | + */ |
|
30 | + public $type = 'kirki-react-colorful'; |
|
31 | + |
|
32 | + /** |
|
33 | + * The control class-name. |
|
34 | + * |
|
35 | + * @access protected |
|
36 | + * @since 0.1 |
|
37 | + * @var string |
|
38 | + */ |
|
39 | + protected $control_class = '\Kirki\Control\ReactColorful'; |
|
40 | + |
|
41 | + /** |
|
42 | + * Whether we should register the control class for JS-templating or not. |
|
43 | + * |
|
44 | + * @access protected |
|
45 | + * @since 0.1 |
|
46 | + * @var bool |
|
47 | + */ |
|
48 | + protected $control_has_js_template = true; |
|
49 | + |
|
50 | + /** |
|
51 | + * Additional logic for the field. |
|
52 | + * |
|
53 | + * @since 4.0.0 |
|
54 | + * @access protected |
|
55 | + * |
|
56 | + * @param array $args The field arguments. |
|
57 | + */ |
|
58 | + protected function init( $args ) { |
|
59 | + |
|
60 | + add_action( 'customize_preview_init', [ $this, 'enqueue_customize_preview_scripts' ] ); |
|
61 | + add_filter( 'kirki_output_control_classnames', [ $this, 'output_control_classnames' ] ); |
|
62 | + |
|
63 | + } |
|
64 | + |
|
65 | + /** |
|
66 | + * Filter arguments before creating the setting. |
|
67 | + * |
|
68 | + * @access public |
|
69 | + * @since 0.1 |
|
70 | + * @param array $args The field arguments. |
|
71 | + * @param WP_Customize_Manager $wp_customize The customizer instance. |
|
72 | + * @return array |
|
73 | + */ |
|
74 | + public function filter_setting_args( $args, $wp_customize ) { |
|
75 | + |
|
76 | + if ( $args['settings'] === $this->args['settings'] ) { |
|
77 | + $args = parent::filter_setting_args( $args, $wp_customize ); |
|
78 | + |
|
79 | + // Set the sanitize-callback if none is defined. |
|
80 | + if ( ! isset( $args['sanitize_callback'] ) || ! $args['sanitize_callback'] ) { |
|
81 | + $args['sanitize_callback'] = [ __CLASS__, 'sanitize' ]; |
|
82 | + |
|
83 | + // If this is a hue control then its value should be an integer. |
|
84 | + if ( isset( $args['mode'] ) && 'hue' === $args['mode'] ) { |
|
85 | + $args['sanitize_callback'] = 'absint'; |
|
86 | + } |
|
87 | + } |
|
88 | + |
|
89 | + // For postMessage/preview purpose, if property is not set, then set it to 'color'. |
|
90 | + if ( isset( $args['output'] ) && ! empty( $args['output'] ) && is_array( $args['output'] ) && ! isset( $args['output']['element'] ) ) { |
|
91 | + foreach ( $args['output'] as $index => $output ) { |
|
92 | + if ( ! isset( $output['property'] ) ) { |
|
93 | + if ( empty( $args['output'][ $index ] ) ) { |
|
94 | + $args['output'][ $index ] = []; |
|
95 | + } |
|
96 | + |
|
97 | + $args['output'][ $index ]['property'] = 'color'; |
|
98 | + } |
|
99 | + } |
|
100 | + } |
|
101 | + } |
|
102 | + |
|
103 | + return $args; |
|
104 | + |
|
105 | + } |
|
106 | + |
|
107 | + /** |
|
108 | + * Filter arguments before creating the control. |
|
109 | + * |
|
110 | + * @access public |
|
111 | + * @since 0.1 |
|
112 | + * @param array $args The field arguments. |
|
113 | + * @param WP_Customize_Manager $wp_customize The customizer instance. |
|
114 | + * @return array |
|
115 | + */ |
|
116 | + public function filter_control_args( $args, $wp_customize ) { |
|
117 | + |
|
118 | + if ( $args['settings'] === $this->args['settings'] ) { |
|
119 | + $args = parent::filter_control_args( $args, $wp_customize ); |
|
120 | + $args['type'] = 'kirki-react-colorful'; |
|
121 | + } |
|
122 | + |
|
123 | + return $args; |
|
124 | + |
|
125 | + } |
|
126 | + |
|
127 | + /** |
|
128 | + * Sanitize colors. |
|
129 | + * |
|
130 | + * @static |
|
131 | + * @access public |
|
132 | + * @since 1.0 |
|
133 | + * |
|
134 | + * @param string|array $value The color. |
|
135 | + * @return string|array |
|
136 | + */ |
|
137 | + public static function sanitize( $value ) { |
|
138 | + |
|
139 | + $sanitized_value = ''; |
|
140 | + |
|
141 | + if ( is_string( $value ) ) { |
|
142 | + $sanitized_value = self::sanitize_color_string( $value ); |
|
143 | + } elseif ( is_array( $value ) ) { |
|
144 | + if ( isset( $value['r'] ) || isset( $value['g'] ) || isset( $value['b'] ) ) { |
|
145 | + $sanitized_value = self::sanitize_color_array( $value, 'rgb' ); |
|
146 | + } elseif ( isset( $value['h'] ) || isset( $value['s'] ) ) { |
|
147 | + if ( isset( $value['l'] ) ) { |
|
148 | + $sanitized_value = self::sanitize_color_array( $value, 'hsl' ); |
|
149 | + } elseif ( isset( $value['v'] ) ) { |
|
150 | + $sanitized_value = self::sanitize_color_array( $value, 'hsv' ); |
|
151 | + } |
|
152 | + } |
|
153 | + } |
|
154 | + |
|
155 | + return $sanitized_value; |
|
156 | + |
|
157 | + } |
|
158 | + |
|
159 | + /** |
|
160 | + * Sanitize single color array. |
|
161 | + * |
|
162 | + * @param array $color The provided color in array format. |
|
163 | + * @param string $color_type The color type. Accepts: rgb, hsl, and hsv. |
|
164 | + * |
|
165 | + * @return array The sanitized color. |
|
166 | + */ |
|
167 | + public static function sanitize_color_array( $color, $color_type = 'rgb' ) { |
|
168 | + |
|
169 | + $keys = [ 'r', 'g', 'b' ]; |
|
170 | + $mins = [ 0, 0, 0 ]; |
|
171 | + $maxs = [ 255, 255, 255 ]; |
|
172 | + |
|
173 | + if ( 'hsl' === $color_type || 'hsv' === $color_type ) { |
|
174 | + $keys = [ 'h', 's', '' ]; |
|
175 | + $keys[2] = isset( $color['v'] ) ? 'v' : 'l'; |
|
176 | + |
|
177 | + $mins = [ 0, 0, 0 ]; |
|
178 | + $maxs = [ 360, 100, 100 ]; |
|
179 | + } |
|
180 | + |
|
181 | + $sanitized_color = []; |
|
182 | + |
|
183 | + $sanitized_color = [ |
|
184 | + $keys[0] => isset( $color[ $keys[0] ] ) ? absint( $color[ $keys[0] ] ) : $mins[0], |
|
185 | + $keys[1] => isset( $color[ $keys[1] ] ) ? absint( $color[ $keys[1] ] ) : $mins[1], |
|
186 | + $keys[2] => isset( $color[ $keys[2] ] ) ? absint( $color[ $keys[2] ] ) : $mins[2], |
|
187 | + ]; |
|
188 | + |
|
189 | + $sanitized_color[ $keys[0] ] = $sanitized_color[ $keys[0] ] < $mins[0] ? $mins[0] : $sanitized_color[ $keys[0] ]; |
|
190 | + $sanitized_color[ $keys[0] ] = $sanitized_color[ $keys[0] ] > $maxs[0] ? $maxs[0] : $sanitized_color[ $keys[0] ]; |
|
191 | + |
|
192 | + $sanitized_color[ $keys[1] ] = $sanitized_color[ $keys[1] ] < $mins[1] ? $mins[1] : $sanitized_color[ $keys[1] ]; |
|
193 | + $sanitized_color[ $keys[1] ] = $sanitized_color[ $keys[1] ] > $maxs[1] ? $maxs[1] : $sanitized_color[ $keys[1] ]; |
|
194 | + |
|
195 | + $sanitized_color[ $keys[2] ] = $sanitized_color[ $keys[2] ] < $mins[2] ? $mins[2] : $sanitized_color[ $keys[2] ]; |
|
196 | + $sanitized_color[ $keys[2] ] = $sanitized_color[ $keys[2] ] > $maxs[2] ? $maxs[2] : $sanitized_color[ $keys[2] ]; |
|
197 | + |
|
198 | + if ( isset( $color['a'] ) ) { |
|
199 | + $sanitized_color['a'] = isset( $color['a'] ) ? filter_var( $color['a'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION ) : 1; |
|
200 | + $sanitized_color['a'] = $sanitized_color['a'] < 0 ? 0 : $sanitized_color['a']; |
|
201 | + $sanitized_color['a'] = $sanitized_color['a'] > 1 ? 1 : $sanitized_color['a']; |
|
202 | + } |
|
203 | + |
|
204 | + return $sanitized_color; |
|
205 | + |
|
206 | + } |
|
207 | + |
|
208 | + /** |
|
209 | + * Sanitize color string. |
|
210 | + * |
|
211 | + * @static |
|
212 | + * @access public |
|
213 | + * @since 1.0 |
|
214 | + * |
|
215 | + * @param string $value The color. |
|
216 | + * @return string |
|
217 | + */ |
|
218 | + public static function sanitize_color_string( $value ) { |
|
219 | + |
|
220 | + $value = strtolower( $value ); |
|
221 | + |
|
222 | + /** |
|
223 | + * This pattern will check and match 3/6/8-character hex, rgb, rgba, hsl, hsla, hsv, and hsva colors. |
|
224 | + * |
|
225 | + * RGB regex: |
|
226 | + * |
|
227 | + * @link https://stackoverflow.com/questions/9585973/javascript-regular-expression-for-rgb-values#answer-9586045 |
|
228 | + * |
|
229 | + * For testing it, you can use these links: |
|
230 | + * |
|
231 | + * @link https://regex101.com/ |
|
232 | + * @link https://regexr.com/ |
|
233 | + * @link https://www.regextester.com/ |
|
234 | + * |
|
235 | + * How to test it? |
|
236 | + * |
|
237 | + * Paste the following code to the test field (of course without the asterisks and spaces in front of them): |
|
238 | + * rgba(255, 255, 0, 0.9) |
|
239 | + * rgb(255, 255, 0) |
|
240 | + * #ff0 |
|
241 | + * #ffff00 |
|
242 | + * hsl(150, 25%, 25%) |
|
243 | + * hsla(250, 25%, 25%, 0.7) |
|
244 | + * hsv(125, 15%, 30%) |
|
245 | + * hsva(125, 15%, 30%, 0.5) |
|
246 | + * |
|
247 | + * And then paste the regex `$pattern` below (without the single quote's start and end) to the regular expression box. |
|
248 | + * Set the flag to use "global" and "multiline". |
|
249 | + */ |
|
250 | + $pattern = '/^(\#[\da-f]{3}|\#[\da-f]{6}|\#[\da-f]{8}|rgba\(((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*,\s*){2}((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*)(,\s*(0\.\d+|1))\)|rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)|hsla\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)(,\s*(0\.\d+|1))\)|hsl\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)\)|hsva\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)(,\s*(0\.\d+|1))\)|hsv\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)\))$/'; |
|
251 | + |
|
252 | + preg_match( $pattern, $value, $matches ); |
|
253 | + |
|
254 | + // Return the 1st match found. |
|
255 | + if ( isset( $matches[0] ) ) { |
|
256 | + if ( is_string( $matches[0] ) ) { |
|
257 | + return $matches[0]; |
|
258 | + } |
|
259 | + |
|
260 | + if ( is_array( $matches[0] ) && isset( $matches[0][0] ) ) { |
|
261 | + return $matches[0][0]; |
|
262 | + } |
|
263 | + } |
|
264 | + |
|
265 | + // If no match was found, return an empty string. |
|
266 | + return ''; |
|
267 | + } |
|
268 | + |
|
269 | + /** |
|
270 | + * Enqueue styles & scripts on 'customize_preview_init' action. |
|
271 | + * |
|
272 | + * @since 4.0.0 |
|
273 | + * @access public |
|
274 | + */ |
|
275 | + public function enqueue_customize_preview_scripts() { |
|
276 | + |
|
277 | + wp_enqueue_script( 'kirki-react-colorful', URL::get_from_path( dirname( dirname( __DIR__ ) ) ) . '/dist/preview.js', [ 'wp-hooks', 'customize-preview' ], $this->control_class::$control_ver, true ); |
|
278 | + |
|
279 | + } |
|
280 | + |
|
281 | + /** |
|
282 | + * Add output control class for react colorful control. |
|
283 | + * |
|
284 | + * @since 4.0.0 |
|
285 | + * @access public |
|
286 | + * |
|
287 | + * @param array $control_classes The existing control classes. |
|
288 | + * @return array |
|
289 | + */ |
|
290 | + public function output_control_classnames( $control_classes ) { |
|
291 | + |
|
292 | + $control_classes['kirki-react-colorful'] = '\Kirki\Field\CSS\ReactColorful'; |
|
293 | + |
|
294 | + return $control_classes; |
|
295 | + |
|
296 | + } |
|
297 | 297 | |
298 | 298 | } |