Completed
Push — develop ( 84d569...bfd647 )
by Aristeides
06:29
created

Kirki_Output   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 221
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 221
rs 8.6
c 0
b 0
f 0
wmc 37
lcom 1
cbo 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A apply_sanitize_callback() 0 14 4
A apply_value_pattern() 0 11 4
C parse_output() 0 50 16
B process_output() 0 11 7
A process_property_value() 0 13 2
A process_value() 0 6 2
A get_styles() 0 3 1
1
<?php
2
/**
3
 * Handles CSS output for fields.
4
 *
5
 * @package     Kirki
6
 * @subpackage  Controls
7
 * @copyright   Copyright (c) 2016, Aristeides Stathopoulos
8
 * @license     http://opensource.org/licenses/https://opensource.org/licenses/MIT
9
 * @since       2.2.0
10
 */
11
12
if ( ! class_exists( 'Kirki_Output' ) ) {
13
14
	/**
15
	 * Handles field CSS output.
16
	 */
17
	class Kirki_Output {
18
19
		/**
20
		 * The Kirki configuration used in the field.
21
		 *
22
		 * @access protected
23
		 * @var string
24
		 */
25
		protected $config_id = 'global';
26
27
		/**
28
		 * The field's `output` argument.
29
		 *
30
		 * @access protected
31
		 * @var array
32
		 */
33
		protected $output = array();
34
35
		/**
36
		 * An array of the generated styles.
37
		 *
38
		 * @access protected
39
		 * @var array
40
		 */
41
		protected $styles = array();
42
43
		/**
44
		 * The value.
45
		 *
46
		 * @access protected
47
		 * @var string|array
48
		 */
49
		protected $value;
50
51
		/**
52
		 * The class constructor.
53
		 *
54
		 * @access public
55
		 * @param string       $config_id The config ID.
56
		 * @param array        $output    The output argument.
57
		 * @param string|array $value     The value.
58
		 */
59
		public function __construct( $config_id, $output, $value ) {
60
61
			$this->config_id = $config_id;
62
			$this->value     = $value;
63
			$this->output    = $output;
64
65
			$this->parse_output();
66
		}
67
68
		/**
69
		 * If we have a sanitize_callback defined, apply it to the value.
70
		 *
71
		 * @param array        $output The output args.
72
		 * @param string|array $value  The value.
73
		 *
74
		 * @return string|array
75
		 */
76
		protected function apply_sanitize_callback( $output, $value ) {
77
78
			if ( isset( $output['sanitize_callback'] ) && null !== $output['sanitize_callback'] ) {
79
80
				// If the sanitize_callback is invalid, return the value.
81
				if ( ! is_callable( $output['sanitize_callback'] ) ) {
82
					return $value;
83
				}
84
				return call_user_func( $output['sanitize_callback'], $this->value );
85
			}
86
87
			return $value;
88
89
		}
90
91
		/**
92
		 * If we have a value_pattern defined, apply it to the value.
93
		 *
94
		 * @param array        $output The output args.
95
		 * @param string|array $value  The value.
96
		 *
97
		 * @return string|array
98
		 */
99
		protected function apply_value_pattern( $output, $value ) {
100
101
			if ( isset( $output['value_pattern'] ) && ! empty( $output['value_pattern'] ) ) {
102
				if ( is_string( $output['value_pattern'] ) ) {
103
					return str_replace( '$', $value, $output['value_pattern'] );
104
				}
105
			}
106
107
			return $value;
108
109
		}
110
111
		/**
112
		 * Parses the output arguments.
113
		 * Calls the process_output method for each of them.
114
		 *
115
		 * @access protected
116
		 */
117
		protected function parse_output() {
118
			foreach ( $this->output as $output ) {
119
				$skip = false;
120
121
				// Apply any sanitization callbacks defined.
122
				$value = $this->apply_sanitize_callback( $output, $this->value );
123
124
				// Skip if value is empty.
125
				if ( '' === $this->value ) {
126
					$skip = true;
127
				}
128
129
				// No need to proceed this if the current value is the same as in the "exclude" value.
130
				if ( isset( $output['exclude'] ) && false !== $output['exclude'] && is_array( $output['exclude'] ) ) {
131
					foreach ( $output['exclude'] as $exclude ) {
132
						if ( is_array( $value ) && is_array( $exclude ) ) {
133
							$diff1 = array_diff( $value, $exclude );
134
							$diff2 = array_diff( $exclude, $value );
135
136
							if ( empty( $diff1 ) && empty( $diff2 ) ) {
137
								$skip = true;
138
							}
139
						}
140
						if ( $skip ) {
141
							continue;
142
						}
143
144
						// Skip if value is defined as excluded.
145
						if ( $exclude === $value ) {
146
							$skip = true;
147
						}
148
					}
149
				}
150
				if ( $skip ) {
151
					continue;
152
				}
153
154
				// Apply any value patterns defined.
155
				$value = $this->apply_value_pattern( $output, $value );
156
157
				if ( isset( $output['element'] ) && is_array( $output['element'] ) ) {
158
					$output['element'] = array_unique( $output['element'] );
159
					sort( $output['element'] );
160
					$output['element'] = implode( ',', $output['element'] );
161
				}
162
163
				$value = $this->process_value( $value, $output );
164
				$this->process_output( $output, $value );
0 ignored issues
show
Bug introduced by
It seems like $value defined by $this->process_value($value, $output) on line 163 can also be of type array; however, Kirki_Output::process_output() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
165
			} // End foreach().
166
		}
167
168
		/**
169
		 * Parses an output and creates the styles array for it.
170
		 *
171
		 * @access protected
172
		 * @param array  $output The field output.
173
		 * @param string $value  The value.
174
		 *
175
		 * @return void
176
		 */
177
		protected function process_output( $output, $value ) {
178
			if ( ! isset( $output['element'] ) || ! isset( $output['property'] ) ) {
179
				return;
180
			}
181
			$output['media_query'] = ( isset( $output['media_query'] ) ) ? $output['media_query'] : 'global';
182
			$output['prefix']      = ( isset( $output['prefix'] ) )      ? $output['prefix']      : '';
183
			$output['units']       = ( isset( $output['units'] ) )       ? $output['units']       : '';
184
			$output['suffix']      = ( isset( $output['suffix'] ) )      ? $output['suffix']      : '';
185
186
			$this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] ] = $output['prefix'] . $value . $output['units'] . $output['suffix'];
187
		}
188
189
		/**
190
		 * Some CSS properties are unique.
191
		 * We need to tweak the value to make everything works as expected.
192
		 *
193
		 * @access protected
194
		 * @param string $property The CSS property.
195
		 * @param string $value    The value.
196
		 *
197
		 * @return array
198
		 */
199
		protected function process_property_value( $property, $value ) {
200
			$properties = apply_filters( 'kirki/' . $this->config_id . '/output/property-classnames', array(
201
				'font-family'         => 'Kirki_Output_Property_Font_Family',
202
				'background-image'    => 'Kirki_Output_Property_Background_Image',
203
				'background-position' => 'Kirki_Output_Property_Background_Position',
204
			) );
205
			if ( array_key_exists( $property, $properties ) ) {
206
				$classname = $properties[ $property ];
207
				$obj = new $classname( $property, $value );
208
				return $obj->get_value();
209
			}
210
			return $value;
211
		}
212
213
		/**
214
		 * Returns the value.
215
		 *
216
		 * @access protected
217
		 * @param string|array $value The value.
218
		 * @param array        $output The field "output".
219
		 * @return string|array
220
		 */
221
		protected function process_value( $value, $output ) {
222
			if ( isset( $output['property'] ) ) {
223
				return $this->process_property_value( $output['property'], $value );
224
			}
225
			return $value;
226
		}
227
228
		/**
229
		 * Exploses the private $styles property to the world
230
		 *
231
		 * @access protected
232
		 * @return array
233
		 */
234
		public function get_styles() {
235
			return $this->styles;
236
		}
237
	}
238
} // End if().
239