Completed
Push — develop ( 2d809e...4b580b )
by Aristeides
03:12
created

Kirki_Modules_CSS::get_instance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Handles the CSS Output of fields.
4
 *
5
 * @package     Kirki
6
 * @category    Modules
7
 * @author      Aristeides Stathopoulos
8
 * @copyright   Copyright (c) 2017, Aristeides Stathopoulos
9
 * @license     http://opensource.org/licenses/https://opensource.org/licenses/MIT
10
 * @since       3.0.0
11
 */
12
13
/**
14
 * The Kirki_Modules_CSS object.
15
 */
16
class Kirki_Modules_CSS {
17
18
	/**
19
	 * The object instance.
20
	 *
21
	 * @static
22
	 * @access private
23
	 * @since 3.0.0
24
	 * @var object
25
	 */
26
	private static $instance;
27
28
	/**
29
	 * Whether we've already processed this or not.
30
	 *
31
	 * @access public
32
	 * @var bool
33
	 */
34
	public $processed = false;
35
36
	/**
37
	 * The CSS array
38
	 *
39
	 * @access public
40
	 * @var array
41
	 */
42
	public static $css_array = array();
43
44
	/**
45
	 * Set to true if you want to use the AJAX method.
46
	 *
47
	 * @access public
48
	 * @var bool
49
	 */
50
	public static $ajax = false;
51
52
	/**
53
	 * The Kirki_CSS_To_File object.
54
	 *
55
	 * @access protected
56
	 * @since 3.0.0
57
	 * @var object
58
	 */
59
	protected $css_to_file;
60
61
	/**
62
	 * Constructor
63
	 *
64
	 * @access protected
65
	 */
66
	protected function __construct() {
67
68
		$class_files = array(
69
			'Kirki_CSS_To_File'                         => '/class-kirki-css-to-file.php',
70
			'Kirki_Modules_CSS_Generator'               => '/class-kirki-modules-css-generator.php',
71
			'Kirki_Output'                              => '/class-kirki-output.php',
72
			'Kirki_Output_Field_Background'             => '/field/class-kirki-output-field-background.php',
73
			'Kirki_Output_Field_Multicolor'             => '/field/class-kirki-output-field-multicolor.php',
74
			'Kirki_Output_Field_Dimensions'             => '/field/class-kirki-output-field-dimensions.php',
75
			'Kirki_Output_Field_Typography'             => '/field/class-kirki-output-field-typography.php',
76
			'Kirki_Output_Property'                     => '/property/class-kirki-output-property.php',
77
			'Kirki_Output_Property_Background_Image'    => '/property/class-kirki-output-property-background-image.php',
78
			'Kirki_Output_Property_Background_Position' => '/property/class-kirki-output-property-background-position.php',
79
			'Kirki_Output_Property_Font_Family'         => '/property/class-kirki-output-property-font-family.php',
80
		);
81
82
		foreach ( $class_files as $class_name => $file ) {
83
			if ( ! class_exists( $class_name ) ) {
84
				include_once wp_normalize_path( dirname( __FILE__ ) . $file );
85
			}
86
		}
87
88
		add_action( 'init', array( $this, 'init' ) );
89
90
	}
91
92
	/**
93
	 * Gets an instance of this object.
94
	 * Prevents duplicate instances which avoid artefacts and improves performance.
95
	 *
96
	 * @static
97
	 * @access public
98
	 * @since 3.0.0
99
	 * @return object
100
	 */
101
	public static function get_instance() {
102
		if ( ! self::$instance ) {
103
			self::$instance = new self();
104
		}
105
		return self::$instance;
106
	}
107
108
	/**
109
	 * Init.
110
	 *
111
	 * @access public
112
	 */
113
	public function init() {
114
115
		Kirki_Modules_Webfonts::get_instance();
116
117
		global $wp_customize;
118
119
		$config   = apply_filters( 'kirki/config', array() );
120
		$priority = 999;
121
		if ( isset( $config['styles_priority'] ) ) {
122
			$priority = absint( $config['styles_priority'] );
123
		}
124
125
		// Allow completely disabling Kirki CSS output.
126
		if ( ( defined( 'KIRKI_NO_OUTPUT' ) && true === KIRKI_NO_OUTPUT ) || ( isset( $config['disable_output'] ) && true === $config['disable_output'] ) ) {
127
			return;
128
		}
129
130
		$method = apply_filters( 'kirki/dynamic_css/method', 'inline' );
131
		if ( $wp_customize ) {
132
			// If we're in the customizer, load inline no matter what.
133
			add_action( 'wp_enqueue_scripts', array( $this, 'inline_dynamic_css' ), $priority );
134
135
			// If we're using file method, on save write the new styles.
136
			if ( 'file' === $method ) {
137
				$this->css_to_file = new Kirki_CSS_To_File();
138
				add_action( 'customize_save_after', array( $this->css_to_file, 'write_file' ) );
139
			}
140
			return;
141
		}
142
143
		if ( 'file' === $method ) {
144
			// Attempt to write the CSS to file.
145
			$this->css_to_file = new Kirki_CSS_To_File();
146
			// If we succesd, load this file.
147
			$failed = get_transient( 'kirki_css_write_to_file_failed' );
148
			// If writing CSS to file hasn't failed, just enqueue this file.
149
			if ( ! $failed ) {
150
				add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_compiled_file' ), $priority );
151
				return;
152
			}
153
		}
154
155
		// If we are in the customizer, load CSS using inline-styles.
156
		// If we are in the frontend AND self::$ajax is true, then load dynamic CSS using AJAX.
157
		if ( ( true === self::$ajax ) || ( isset( $config['inline_css'] ) && false === $config['inline_css'] ) ) {
158
			add_action( 'wp_enqueue_scripts', array( $this, 'frontend_styles' ), $priority );
159
			add_action( 'wp_ajax_kirki_dynamic_css', array( $this, 'ajax_dynamic_css' ) );
160
			add_action( 'wp_ajax_nopriv_kirki_dynamic_css', array( $this, 'ajax_dynamic_css' ) );
161
			return;
162
		}
163
164
		// If we got this far then add styles inline.
165
		add_action( 'wp_enqueue_scripts', array( $this, 'inline_dynamic_css' ), $priority );
166
	}
167
168
	/**
169
	 * Enqueues compiled CSS file.
170
	 *
171
	 * @access public
172
	 * @since 3.0.0
173
	 */
174
	public function enqueue_compiled_file() {
175
176
		wp_enqueue_style( 'kirki-styles', $this->css_to_file->get_url() );
177
178
	}
179
	/**
180
	 * Adds inline styles.
181
	 *
182
	 * @access public
183
	 */
184
	public function inline_dynamic_css() {
185
		$configs = Kirki::$config;
186
		if ( ! $this->processed ) {
187
			foreach ( $configs as $config_id => $args ) {
188
				if ( isset( $args['disable_output'] ) && true === $args['disable_output'] ) {
189
					continue;
190
				}
191
				$styles = self::loop_controls( $config_id );
192
				$styles = apply_filters( "kirki/{$config_id}/dynamic_css", $styles );
193
				if ( ! empty( $styles ) ) {
194
					wp_enqueue_style( 'kirki-styles-' . $config_id, trailingslashit( Kirki::$url ) . 'assets/css/kirki-styles.css', null, null );
195
					wp_add_inline_style( 'kirki-styles-' . $config_id, $styles );
196
				}
197
			}
198
			$this->processed = true;
199
		}
200
	}
201
202
	/**
203
	 * Get the dynamic-css.php file
204
	 *
205
	 * @access public
206
	 */
207
	public function ajax_dynamic_css() {
208
		require wp_normalize_path( Kirki::$path . '/modules/css/dynamic-css.php' );
209
		exit;
210
	}
211
212
	/**
213
	 * Enqueues the ajax stylesheet.
214
	 *
215
	 * @access public
216
	 */
217
	public function frontend_styles() {
218
		wp_enqueue_style( 'kirki-styles-php', admin_url( 'admin-ajax.php' ) . '?action=kirki_dynamic_css', null, null );
219
	}
220
221
	/**
222
	 * Loop through all fields and create an array of style definitions.
223
	 *
224
	 * @static
225
	 * @access public
226
	 * @param string $config_id The configuration ID.
227
	 */
228
	public static function loop_controls( $config_id ) {
229
230
		// Get an instance of the Kirki_Modules_CSS_Generator class.
231
		// This will make sure google fonts and backup fonts are loaded.
232
		Kirki_Modules_CSS_Generator::get_instance();
233
234
		$fields = Kirki::$fields;
235
		$css    = array();
236
237
		// Early exit if no fields are found.
238
		if ( empty( $fields ) ) {
239
			return;
240
		}
241
242
		foreach ( $fields as $field ) {
243
244
			// Only process fields that belong to $config_id.
245
			if ( $config_id !== $field['kirki_config'] ) {
246
				continue;
247
			}
248
249
			// Only continue if field dependencies are met.
250
			if ( ! empty( $field['required'] ) ) {
251
				$valid = true;
252
253
				foreach ( $field['required'] as $requirement ) {
254
					if ( isset( $requirement['setting'] ) && isset( $requirement['value'] ) && isset( $requirement['operator'] ) ) {
255
						$controller_value = Kirki_Values::get_value( $config_id, $requirement['setting'] );
256
						if ( ! Kirki_Active_Callback::compare( $controller_value, $requirement['value'], $requirement['operator'] ) ) {
257
							$valid = false;
258
						}
259
					}
260
				}
261
262
				if ( ! $valid ) {
263
					continue;
264
				}
265
			}
266
267
			// Only continue if $field['output'] is set.
268
			if ( isset( $field['output'] ) && ! empty( $field['output'] ) ) {
269
				$css = Kirki_Helper::array_replace_recursive( $css, Kirki_Modules_CSS_Generator::css( $field ) );
270
271
				// Add the globals.
272
				if ( isset( self::$css_array[ $config_id ] ) && ! empty( self::$css_array[ $config_id ] ) ) {
273
					Kirki_Helper::array_replace_recursive( $css, self::$css_array[ $config_id ] );
274
				}
275
			}
276
		}
277
278
		$css = apply_filters( "kirki/{$config_id}/styles", $css );
279
280
		if ( is_array( $css ) ) {
281
			return Kirki_Modules_CSS_Generator::styles_parse( Kirki_Modules_CSS_Generator::add_prefixes( $css ) );
282
		}
283
	}
284
}
285