Completed
Push — develop ( ac771f...dcd6b8 )
by Aristeides
02:40
created

Kirki_Field_Typography::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 2
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Override field methods
4
 *
5
 * @package     Kirki
6
 * @subpackage  Controls
7
 * @copyright   Copyright (c) 2017, Aristeides Stathopoulos
8
 * @license     http://opensource.org/licenses/https://opensource.org/licenses/MIT
9
 * @since       2.2.7
10
 */
11
12
/**
13
 * Field overrides.
14
 */
15
class Kirki_Field_Typography extends Kirki_Field {
16
17
	/**
18
	 * Sets the control type.
19
	 *
20
	 * @access protected
21
	 */
22
	protected function set_type() {
23
24
		$this->type = 'kirki-typography';
25
26
	}
27
28
	/**
29
	 * Helper for the static sanitization.
30
	 *
31
	 * @static
32
	 * @since 3.0.10
33
	 * @var array
34
	 */
35
	private static $static_default = array();
36
37
	/**
38
	 * The class constructor.
39
	 * Parses and sanitizes all field arguments.
40
	 * Then it adds the field to Kirki::$fields.
41
	 *
42
	 * @access public
43
	 * @param string $config_id    The ID of the config we want to use.
44
	 *                             Defaults to "global".
45
	 *                             Configs are handled by the Kirki_Config class.
46
	 * @param array  $args         The arguments of the field.
47
	 */
48
	public function __construct( $config_id = 'global', $args = array() ) {
49
		parent::__construct( $config_id, $args );
50
		$this->set_default();
51
		self::$static_default = $this->default;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->default can also be of type string or boolean. However, the property $static_default is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
52
	}
53
54
	/**
55
	 * Sets the default value.
56
	 *
57
	 * @access protected
58
	 */
59
	protected function set_default() {
60
61
		// Accomodate the use of font-weight and convert to variant.
62
		if ( isset( $this->default['font-weight'] ) ) {
63
			$this->default['variant'] = ( 'regular' === $this->default['font-weight'] ) ? 400 : (string) intval( $this->default['font-weight'] );
64
		}
65
66
		// Make sure letter-spacing has units.
67
		if ( isset( $this->default['letter-spacing'] ) && is_numeric( $this->default['letter-spacing'] ) && $this->default['letter-spacing'] ) {
68
			$this->default['letter-spacing'] .= 'px';
69
		}
70
71
		// Make sure we use "subsets" instead of "subset".
72
		if ( isset( $this->default['subset'] ) && ! empty( $this->default['subset'] ) && ( ! isset( $this->default['subsets'] ) || empty( $this->default['subsets'] ) ) ) {
73
			$this->default['subsets'] = $this->default['subset'];
74
		}
75
	}
76
77
	/**
78
	 * Sets the $sanitize_callback
79
	 *
80
	 * @access protected
81
	 */
82
	protected function set_sanitize_callback() {
83
84
		// If a custom sanitize_callback has been defined,
85
		// then we don't need to proceed any further.
86
		if ( ! empty( $this->sanitize_callback ) ) {
87
			return;
88
		}
89
		$this->sanitize_callback = array( __CLASS__, 'sanitize' );
90
91
	}
92
93
	/**
94
	 * Sets the $js_vars
95
	 *
96
	 * @access protected
97
	 */
98
	protected function set_js_vars() {
99
100
		if ( ! is_array( $this->js_vars ) ) {
101
			$this->js_vars = array();
102
		}
103
104
		// Check if transport is set to auto.
105
		// If not, then skip the auto-calculations and exit early.
106
		if ( 'auto' !== $this->transport ) {
107
			return;
108
		}
109
110
		// Set transport to refresh initially.
111
		// Serves as a fallback in case we failt to auto-calculate js_vars.
112
		$this->transport = 'refresh';
113
114
		$js_vars = array();
115
116
		// Try to auto-generate js_vars.
117
		// First we need to check if js_vars are empty, and that output is not empty.
118
		if ( ! empty( $this->output ) ) {
119
120
			// Start going through each item in the $output array.
121
			foreach ( $this->output as $output ) {
122
123
				// If 'element' or 'property' are not defined, skip this.
124
				if ( ! isset( $output['element'] ) ) {
125
					continue;
126
				}
127
				if ( is_array( $output['element'] ) ) {
128
					$output['element'] = implode( ',', $output['element'] );
129
				}
130
131
				// If we got this far, it's safe to add this.
132
				$js_vars[] = $output;
133
			}
134
135
			// Did we manage to get all the items from 'output'?
136
			// If not, then we're missing something so don't add this.
137
			if ( count( $js_vars ) !== count( $this->output ) ) {
138
				return;
139
			}
140
			$this->js_vars   = $js_vars;
141
			$this->transport = 'postMessage';
142
143
		}
144
145
	}
146
147
	/**
148
	 * Sanitizes typography controls
149
	 *
150
	 * @static
151
	 * @since 2.2.0
152
	 * @param array $value The value.
153
	 * @return array
154
	 */
155
	public static function sanitize( $value ) {
156
157
		if ( ! is_array( $value ) ) {
158
			return array();
159
		}
160
161
		foreach ( $value as $key => $val ) {
162
			switch ( $key ) {
163
				case 'font-family':
164
					$value['font-family'] = esc_attr( $val );
165
					break;
166
				case 'font-weight':
167
					if ( isset( $value['variant'] ) ) {
168
						break;
169
					}
170
					$value['variant'] = $val;
171
					if ( isset( $value['font-style'] ) && 'italic' === $value['font-style'] ) {
172
						$value['variant'] = ( '400' !== $val || 400 !== $val ) ? $value['variant'] . 'italic' : 'italic';
173
					}
174
					break;
175
				case 'variant':
176
					// Use 'regular' instead of 400 for font-variant.
177
					$value['variant'] = ( 400 === $val || '400' === $val ) ? 'regular' : $val;
178
					// Get font-weight from variant.
179
					$value['font-weight'] = filter_var( $value['variant'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION );
180
					$value['font-weight'] = ( 'regular' === $value['variant'] || 'italic' === $value['variant'] ) ? 400 : absint( $value['font-weight'] );
181
					// Get font-style from variant.
182
					if ( ! isset( $value['font-style'] ) ) {
183
						$value['font-style'] = ( false === strpos( $value['variant'], 'italic' ) ) ? 'normal' : 'italic';
184
					}
185
					break;
186
				case 'subset':
187
					// Make sure the saved value is "subsets" (plural) and not "subset".
188
					// This is for compatibility with older versions.
189
					if ( ! empty( $value['subset'] ) && ! isset( $value['subsets'] ) || empty( $value['subset'] ) ) {
190
						$value['subsets'] = $value['subset'];
191
					}
192
					unset( $value['subset'] );
193
					// Make sure we're using a valid subset.
194
					$valid_subsets = Kirki_Fonts::get_google_font_subsets();
195
					$subsets_ok = array();
196
					$value['subsets'] = (array) $value['subsets'];
197
					foreach ( $value['subsets'] as $subset ) {
198
						if ( array_key_exists( $subset, $valid_subsets ) ) {
199
							$subsets_ok[] = $subset;
200
						}
201
					}
202
					$value['subsets'] = $subsets_ok;
203
					break;
204
				case 'font-size':
205
				case 'letter-spacing':
206
				case 'word-spacing':
207
				case 'line-height':
208
					$value[ $key ] = Kirki_Sanitize_Values::css_dimension( $val );
209
					break;
210
				case 'text-align':
211
					if ( ! in_array( $val, array( 'inherit', 'left', 'center', 'right', 'justify' ), true ) ) {
212
						$value['text-align'] = 'inherit';
213
					}
214
					break;
215
				case 'text-transform':
216
					if ( ! in_array( $val, array( 'none', 'capitalize', 'uppercase', 'lowercase', 'initial', 'inherit' ), true ) ) {
217
						$value['text-transform'] = 'none';
218
					}
219
					break;
220
				case 'color':
221
					$value['color'] = ariColor::newColor( $val )->toCSS( 'hex' );
222
					break;
223
			} // End switch().
224
		} // End foreach().
225
226
		foreach ( array( 'font-size', 'letter-spacing', 'word-spacing', 'line-height', 'text-align', 'color' ) as $property ) {
227
			if ( is_array( self::$static_default ) && ! isset( self::$static_default[ $property ] ) ) {
228
				unset( $value[ $property ] );
229
			}
230
		}
231
		return $value;
232
	}
233
234
	/**
235
	 * Sets the $choices
236
	 *
237
	 * @access protected
238
	 * @since 3.0.0
239
	 */
240
	protected function set_choices() {
241
242
		if ( ! is_customize_preview() ) {
243
			return;
244
		}
245
		if ( ! is_array( $this->choices ) ) {
246
			$this->choices = array();
247
		}
248
		$this->choices = wp_parse_args(
249
			$this->choices, array(
250
				'variant' => array(),
251
				'fonts'   => array(
252
					'standard' => array(),
253
					'google'   => array(),
254
				),
255
			)
256
		);
257
	}
258
}
259