Completed
Push — contact-form/move-export-rebas... ( e50f9a...56461e )
by George
21:14 queued 09:14
created

Jetpack_Custom_CSS_Enhancements::add_hooks()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 34
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 22
nc 1
nop 0
dl 0
loc 34
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * Alternate Custom CSS source for 4.7 compat.
4
 *
5
 * @since 4.4.2
6
 *
7
 * @package Jetpack
8
 */
9
10
/**
11
 * Class Jetpack_Custom_CSS_Enhancements
12
 */
13
class Jetpack_Custom_CSS_Enhancements {
14
	/**
15
	 * Set up the actions and filters needed for our compatability layer on top of core's Custom CSS implementation.
16
	 */
17
	public static function add_hooks() {
18
		add_action( 'init', array( __CLASS__, 'init' ) );
19
		add_action( 'admin_menu', array( __CLASS__, 'admin_menu' ) );
20
		add_action( 'customize_controls_enqueue_scripts', array( __CLASS__, 'customize_controls_enqueue_scripts' ) );
21
		add_action( 'customize_register', array( __CLASS__, 'customize_register' ) );
22
		add_filter( 'map_meta_cap', array( __CLASS__, 'map_meta_cap' ), 20, 2 );
23
		add_action( 'customize_preview_init', array( __CLASS__, 'customize_preview_init' ) );
24
		add_filter( '_wp_post_revision_fields', array( __CLASS__, '_wp_post_revision_fields' ), 10, 2 );
25
		add_action( 'load-revision.php', array( __CLASS__, 'load_revision_php' ) );
26
27
		add_action( 'wp_enqueue_scripts', array( __CLASS__, 'wp_enqueue_scripts' ) );
28
29
		// Handle Sass/LESS.
30
		add_filter( 'customize_value_custom_css', array( __CLASS__, 'customize_value_custom_css' ), 10, 2 );
31
		add_filter( 'customize_update_custom_css_post_content_args', array( __CLASS__, 'customize_update_custom_css_post_content_args' ), 10, 3 );
32
		add_filter( 'update_custom_css_data', array( __CLASS__, 'update_custom_css_data' ), 10, 2 );
33
34
		// Handle Sass/LESS.
35
		add_filter( 'customize_value_custom_css', array( __CLASS__, 'customize_value_custom_css' ), 10, 2 );
36
		add_filter( 'customize_update_custom_css_post_content_args', array( __CLASS__, 'customize_update_custom_css_post_content_args' ), 10, 3 );
37
38
		// Stuff for stripping out the theme's default stylesheet...
39
		add_filter( 'stylesheet_uri', array( __CLASS__, 'style_filter' ) );
40
		add_filter( 'safecss_skip_stylesheet', array( __CLASS__, 'preview_skip_stylesheet' ) );
41
42
		// Stuff for overriding content width...
43
		add_action( 'customize_preview_init', array( __CLASS__, 'preview_content_width' ) );
44
		add_filter( 'jetpack_content_width', array( __CLASS__, 'jetpack_content_width' ) );
45
		add_filter( 'editor_max_image_size', array( __CLASS__, 'editor_max_image_size' ), 10, 3 );
46
		add_action( 'template_redirect', array( __CLASS__, 'set_content_width' ) );
47
		add_action( 'admin_init', array( __CLASS__, 'set_content_width' ) );
48
49
		// Stuff?
50
	}
51
52
	/**
53
	 * Things that we do on init.
54
	 */
55
	public static function init() {
56
		$min = '.min';
0 ignored issues
show
Unused Code introduced by
$min is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
57
		if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
58
			$min = '';
0 ignored issues
show
Unused Code introduced by
$min is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
59
		}
60
61
		wp_register_style( 'jetpack-codemirror',      plugins_url( 'custom-css/css/codemirror.css', __FILE__ ), array(), '20120905' );
62
		wp_register_style( 'jetpack-customizer-css',  plugins_url( 'custom-css/css/customizer-control.css', __FILE__ ), array( 'jetpack-codemirror' ), '20140728' );
63
		wp_register_script( 'jetpack-codemirror',     plugins_url( 'custom-css/js/codemirror.min.js', __FILE__ ), array(), '3.16', true );
64
		wp_register_script( 'jetpack-customizer-css', plugins_url( 'custom-css/js/core-customizer-css.js', __FILE__ ), array( 'customize-controls', 'underscore', 'jetpack-codemirror' ), JETPACK__VERSION, true );
65
66
		wp_register_script( 'jetpack-customizer-css-preview', plugins_url( 'custom-css/js/core-customizer-css-preview.js', __FILE__ ), array( 'customize-selective-refresh' ), JETPACK__VERSION, true );
67
68
		remove_action( 'wp_head', 'wp_custom_css_cb', 11 ); // 4.7.0 had it at 11, 4.7.1 moved it to 101.
69
		remove_action( 'wp_head', 'wp_custom_css_cb', 101 );
70
		add_action( 'wp_head', array( __CLASS__, 'wp_custom_css_cb' ), 101 );
71
72
		if ( isset( $_GET['custom-css'] ) ) {
73
			self::print_linked_custom_css();
74
		}
75
	}
76
77
	/**
78
	 * Things that we do on init when the Customize Preview is loading.
79
	 */
80
	public static function customize_preview_init() {
81
		add_filter( 'wp_get_custom_css', array( __CLASS__, 'customize_preview_wp_get_custom_css' ) );
82
	}
83
84
	/**
85
	 * Print the current Custom CSS. This is for linking instead of printing directly.
86
	 */
87
	public static function print_linked_custom_css() {
88
		header( 'Content-type: text/css' );
89
		header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + YEAR_IN_SECONDS ) . ' GMT' );
90
		echo wp_get_custom_css();
91
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method print_linked_custom_css() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
92
	}
93
94
	/**
95
	 * Re-map the Edit CSS capability.
96
	 *
97
	 * Core, by default, restricts this to users that have `unfiltered_html` which
98
	 * would make the feature unusable in multi-site by non-super-admins, due to Core
99
	 * not shipping any solid sanitization.
100
	 *
101
	 * We're expanding who can use it, and then conditionally applying CSSTidy
102
	 * sanitization to users that do not have the `unfiltered_html` capability.
103
	 *
104
	 * @param array  $caps Returns the user's actual capabilities.
105
	 * @param string $cap  Capability name.
106
	 *
107
	 * @return array $caps
108
	 */
109
	public static function map_meta_cap( $caps, $cap ) {
110
		if ( 'edit_css' === $cap ) {
111
			$caps = array( 'edit_theme_options' );
112
		}
113
		return $caps;
114
	}
115
116
	/**
117
	 * Handle our admin menu item and legacy page declaration.
118
	 */
119
	public static function admin_menu() {
120
		// Add in our legacy page to support old bookmarks and such.
121
		add_submenu_page( null, __( 'CSS', 'jetpack' ), __( 'Edit CSS', 'jetpack' ), 'edit_theme_options', 'editcss', array( __CLASS__, 'admin_page' ) );
122
123
		// Add in our new page slug that will redirect to the customizer.
124
		$hook = add_theme_page( __( 'CSS', 'jetpack' ), __( 'Edit CSS', 'jetpack' ), 'edit_theme_options', 'editcss-customizer-redirect', array( __CLASS__, 'admin_page' ) );
125
		add_action( "load-{$hook}", array( __CLASS__, 'customizer_redirect' ) );
126
	}
127
128
	/**
129
	 * Handle the redirect for the customizer.  This is necessary because
130
	 * we can't directly add customizer links to the admin menu.
131
	 *
132
	 * There is a core patch in trac that would make this unnecessary.
133
	 *
134
	 * @link https://core.trac.wordpress.org/ticket/39050
135
	 */
136
	public static function customizer_redirect() {
137
		wp_safe_redirect( self::customizer_link( array(
138
			'return_url' => wp_get_referer(),
139
		) ) );
140
	}
141
142
	/**
143
	 * Shows Preprocessor code in the Revisions screen, and ensures that post_content_filtered
144
	 * is maintained on revisions
145
	 *
146
	 * @param array $fields  Post fields pertinent to revisions.
147
	 * @param array $post    A post array being processed for insertion as a post revision.
148
	 *
149
	 * @return array $fields Modified array to include post_content_filtered.
150
	 */
151
	public static function _wp_post_revision_fields( $fields, $post ) {
152
		// None of the fields in $post are required to be passed in this filter.
153
		if ( ! isset( $post['post_type'], $post['ID'] ) ) {
154
			return $fields;
155
		}
156
157
		// If we're passed in a revision, go get the main post instead.
158
		if ( 'revision' === $post['post_type'] ) {
159
			$main_post_id = wp_is_post_revision( $post['ID'] );
160
			$post = get_post( $main_post_id, ARRAY_A );
161
		}
162
		if ( 'custom_css' === $post['post_type'] ) {
163
			$fields['post_content'] = __( 'CSS', 'jetpack' );
164
			$fields['post_content_filtered'] = __( 'Preprocessor', 'jetpack' );
165
		}
166
		return $fields;
167
	}
168
169
	/**
170
	 * Get the published custom CSS post.
171
	 *
172
	 * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the current theme.
173
	 * @return WP_Post|null
174
	 */
175
	public static function get_css_post( $stylesheet = '' ) {
176
		return wp_get_custom_css_post( $stylesheet );
177
	}
178
179
	/**
180
	 * Override Core's `wp_custom_css_cb` method to provide linking to custom css.
181
	 */
182
	public static function wp_custom_css_cb() {
183
		$styles = wp_get_custom_css();
184
		if ( strlen( $styles ) > 2000 && ! is_customize_preview() ) :
185
			// Add a cache buster to the url.
186
			$url = home_url( '/' );
187
			$url = add_query_arg( 'custom-css', substr( md5( $styles ), -10 ), $url );
188
			?>
189
			<link rel="stylesheet" type="text/css" id="wp-custom-css" href="<?php echo esc_url( $url ); ?>" />
190
		<?php elseif ( $styles || is_customize_preview() ) : ?>
191
			<style type="text/css" id="wp-custom-css">
192
				<?php echo strip_tags( $styles ); // Note that esc_html() cannot be used because `div &gt; span` is not interpreted properly. ?>
193
			</style>
194
		<?php endif;
195
	}
196
197
	/**
198
	 * Get the ID of a Custom CSS post tying to a given stylesheet.
199
	 *
200
	 * @param string $stylesheet Stylesheet name.
201
	 *
202
	 * @return int $post_id Post ID.
203
	 */
204
	public static function post_id( $stylesheet = '' ) {
205
		$post = self::get_css_post( $stylesheet );
206
		if ( $post instanceof WP_Post ) {
0 ignored issues
show
Bug introduced by
The class WP_Post does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
207
			return $post->ID;
208
		}
209
		return 0;
210
	}
211
212
	/**
213
	 * Partial for use in the Customizer.
214
	 */
215
	public static function echo_custom_css_partial() {
216
		echo wp_get_custom_css();
217
	}
218
219
	/**
220
	 * Admin page!
221
	 *
222
	 * This currently has two main uses -- firstly to display the css for an inactive
223
	 * theme if there are no revisions attached it to a legacy bug, and secondly to
224
	 * handle folks that have bookmarkes in their browser going to the old page for
225
	 * managing Custom CSS in Jetpack.
226
	 *
227
	 * If we ever add back in a non-Customizer CSS editor, this would be the place.
228
	 */
229
	public static function admin_page() {
230
		$post = null;
231
		$stylesheet = null;
232
		if ( isset( $_GET['id'] ) ) {
233
			$post_id = absint( $_GET['id'] );
234
			$post = get_post( $post_id );
235
			if ( $post instanceof WP_Post && 'custom_css' === $post->post_type ) {
0 ignored issues
show
Bug introduced by
The class WP_Post does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
236
				$stylesheet = $post->post_title;
237
			}
238
		}
239
		?>
240
		<div class="wrap">
241
			<?php self::revisions_switcher_box( $stylesheet ); ?>
242
			<h1>
243
				<?php
244
				if ( $post ) {
245
					printf( 'Custom CSS for &#8220;%1$s&#8221;', wp_get_theme( $stylesheet )->Name );
246
				} else {
247
					esc_html_e( 'Custom CSS', 'jetpack' );
248
				}
249
				if ( current_user_can( 'customize' ) ) {
250
					printf(
251
						' <a class="page-title-action hide-if-no-customize" href="%1$s">%2$s</a>',
252
						esc_url( self::customizer_link() ),
253
						esc_html__( 'Manage with Live Preview', 'jetpack' )
254
					);
255
				}
256
				?>
257
			</h1>
258
			<p><?php esc_html_e( 'Custom CSS is now managed in the Customizer.', 'jetpack' ); ?></p>
259
			<?php if ( $post ) : ?>
260
				<div class="revisions">
261
					<h3><?php esc_html_e( 'CSS', 'jetpack' ); ?></h3>
262
					<textarea class="widefat" readonly><?php echo esc_textarea( $post->post_content ); ?></textarea>
263
					<?php if ( $post->post_content_filtered ) : ?>
264
						<h3><?php esc_html_e( 'Preprocessor', 'jetpack' ); ?></h3>
265
						<textarea class="widefat" readonly><?php echo esc_textarea( $post->post_content_filtered ); ?></textarea>
266
					<?php endif; ?>
267
				</div>
268
			<?php endif; ?>
269
		</div>
270
271
		<style>
272
			.other-themes-wrap {
273
				float: right;
274
				background-color: #fff;
275
				-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.1);
276
				box-shadow: 0 1px 3px rgba(0,0,0,0.1);
277
				padding: 5px 10px;
278
				margin-bottom: 10px;
279
			}
280
			.other-themes-wrap label {
281
				display: block;
282
				margin-bottom: 10px;
283
			}
284
			.other-themes-wrap select {
285
				float: left;
286
				width: 77%;
287
			}
288
			.other-themes-wrap button {
289
				float: right;
290
				width: 20%;
291
			}
292
			.revisions {
293
				clear: both;
294
			}
295
			.revisions textarea {
296
				min-height: 300px;
297
				background: #fff;
298
			}
299
		</style>
300
		<script>
301
			(function($){
302
				var $switcher = $('.other-themes-wrap');
303
				$switcher.find('button').on('click', function(e){
304
					e.preventDefault();
305
					if ( $switcher.find('select').val() ) {
306
						window.location.href = $switcher.find('select').val();
307
					}
308
				});
309
			})(jQuery);
310
		</script>
311
		<?php
312
	}
313
314
	/**
315
	 * Build the URL to deep link to the Customizer.
316
	 *
317
	 * You can modify the return url via $args.
318
	 *
319
	 * @param array $args Array of parameters.
320
	 * @return string
321
	 */
322
	public static function customizer_link( $args = array() ) {
323
		$args = wp_parse_args( $args, array(
324
			'return_url' => urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ),
325
		) );
326
327
		return add_query_arg(
328
			array(
329
				array(
330
					'autofocus' => array(
331
						'section' => 'custom_css',
332
					),
333
				),
334
				'return' => $args['return_url'],
335
			),
336
			admin_url( 'customize.php' )
337
		);
338
	}
339
340
	/**
341
	 * Handle the enqueueing and localizing for scripts to be used in the Customizer.
342
	 */
343
	public static function customize_controls_enqueue_scripts() {
344
		wp_enqueue_style( 'jetpack-customizer-css' );
345
		wp_enqueue_script( 'jetpack-customizer-css' );
346
347
		$content_help = __( 'Set a different content width for full size images.', 'jetpack' );
348
		if ( ! empty( $GLOBALS['content_width'] ) ) {
349
			$content_help .= sprintf(
350
				_n( ' The default content width for the <strong>%1$s</strong> theme is %2$d pixel.', ' The default content width for the <strong>%1$s</strong> theme is %2$d pixels.', intval( $GLOBALS['content_width'] ), 'jetpack' ),
351
				wp_get_theme()->Name,
352
				intval( $GLOBALS['content_width'] )
353
			);
354
		}
355
356
		wp_localize_script( 'jetpack-customizer-css', '_jp_css_settings', array(
357
			/** This filter is documented in modules/custom-css/custom-css.php */
358
			'useRichEditor' => ! jetpack_is_mobile() && apply_filters( 'safecss_use_ace', true ),
359
			'areThereCssRevisions' => self::are_there_css_revisions(),
360
			'revisionsUrl' => self::get_revisions_url(),
361
			'cssHelpUrl' => '//en.support.wordpress.com/custom-design/editing-css/',
362
			'l10n' => array(
363
				'mode'           => __( 'Start Fresh', 'jetpack' ),
364
				'mobile'         => __( 'On Mobile', 'jetpack' ),
365
				'contentWidth'   => $content_help,
366
				'revisions'      => _x( 'See full history', 'Toolbar button to see full CSS revision history', 'jetpack' ),
367
				'css_help_title' => _x( 'Help', 'Toolbar button to get help with custom CSS', 'jetpack' ),
368
			),
369
		));
370
	}
371
372
	/**
373
	 * Check whether there are CSS Revisions for a given theme.
374
	 *
375
	 * Going forward, there should always be, but this was necessitated
376
	 * early on by https://core.trac.wordpress.org/ticket/30854
377
	 *
378
	 * @param string $stylesheet Stylesheet name.
379
	 *
380
	 * @return bool|null|WP_Post
381
	 */
382
	public static function are_there_css_revisions( $stylesheet = '' ) {
383
		$post = wp_get_custom_css_post( $stylesheet );
384
		if ( empty( $post ) ) {
385
			return $post;
386
		}
387
		return (bool) wp_get_post_revisions( $post );
388
	}
389
390
	/**
391
	 * Core doesn't have a function to get the revisions url for a given post ID.
392
	 *
393
	 * @param string $stylesheet Stylesheet name.
394
	 *
395
	 * @return null|string|void
396
	 */
397
	public static function get_revisions_url( $stylesheet = '' ) {
398
		$post = wp_get_custom_css_post( $stylesheet );
399
400
		// If we have any currently saved customizations...
401
		if ( $post instanceof WP_Post ) {
0 ignored issues
show
Bug introduced by
The class WP_Post does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
402
			$revisions = wp_get_post_revisions( $post->ID, array( 'posts_per_page' => 1 ) );
403
			if ( empty( $revisions ) || is_wp_error( $revisions ) ) {
404
				return admin_url( 'themes.php?page=editcss' );
405
			}
406
			$revision = reset( $revisions );
407
			return get_edit_post_link( $revision->ID );
408
		}
409
410
		return admin_url( 'themes.php?page=editcss' );
411
	}
412
413
	/**
414
	 * Get a map of all theme names and theme stylesheets for mapping stuff.
415
	 *
416
	 * @return array
417
	 */
418
	public static function get_themes() {
419
		$themes = wp_get_themes( array( 'errors' => null ) );
420
		$all = array();
421
		foreach ( $themes as $theme ) {
422
			$all[ $theme->name ] = $theme->stylesheet;
423
		}
424
		return $all;
425
	}
426
427
	/**
428
	 * When we need to get all themes that have Custom CSS saved.
429
	 *
430
	 * @return array
431
	 */
432
	public static function get_all_themes_with_custom_css() {
433
		$themes = self::get_themes();
434
		$custom_css = get_posts( array(
435
			'post_type'   => 'custom_css',
436
			'post_status' => get_post_stati(),
437
			'number'      => -1,
438
			'order'       => 'DESC',
439
			'orderby'     => 'modified',
440
		) );
441
		$return = array();
442
443
		foreach ( $custom_css as $post ) {
444
			$stylesheet = $post->post_title;
445
			$label      = array_search( $stylesheet, $themes );
446
447
			if ( ! $label ) {
448
				continue;
449
			}
450
451
			$return[ $stylesheet ] = array(
452
				'label' => $label,
453
				'post'  => $post,
454
			);
455
		}
456
457
		return $return;
458
	}
459
460
	/**
461
	 * Handle the enqueueing of scripts for customize previews.
462
	 */
463
	public static function wp_enqueue_scripts() {
464
		if ( is_customize_preview() ) {
465
			wp_enqueue_script( 'jetpack-customizer-css-preview' );
466
			wp_localize_script( 'jetpack-customizer-css-preview', 'jpCustomizerCssPreview', array(
467
				/** This filter is documented in modules/custom-css/custom-css.php */
468
				'preprocessors' => apply_filters( 'jetpack_custom_css_preprocessors', array() ),
469
			));
470
		}
471
	}
472
473
	/**
474
	 * Sanitize the CSS for users without `unfiltered_html`.
475
	 *
476
	 * @param string $css  Input CSS.
477
	 * @param array  $args Array of CSS options.
478
	 *
479
	 * @return mixed|string
480
	 */
481
	public static function sanitize_css( $css, $args = array() ) {
482
		$args = wp_parse_args( $args, array(
483
			'force'        => false,
484
			'preprocessor' => null,
485
		) );
486
487
		if ( $args['force'] || ! current_user_can( 'unfiltered_html' ) ) {
488
489
			$warnings = array();
490
491
			safecss_class();
492
			$csstidy = new csstidy();
493
			$csstidy->optimise = new safecss( $csstidy );
0 ignored issues
show
Documentation introduced by
$csstidy is of type object<csstidy>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
494
495
			$csstidy->set_cfg( 'remove_bslash',              false );
496
			$csstidy->set_cfg( 'compress_colors',            false );
497
			$csstidy->set_cfg( 'compress_font-weight',       false );
498
			$csstidy->set_cfg( 'optimise_shorthands',        0 );
499
			$csstidy->set_cfg( 'remove_last_;',              false );
500
			$csstidy->set_cfg( 'case_properties',            false );
501
			$csstidy->set_cfg( 'discard_invalid_properties', true );
502
			$csstidy->set_cfg( 'css_level',                  'CSS3.0' );
503
			$csstidy->set_cfg( 'preserve_css',               true );
504
			$csstidy->set_cfg( 'template',                   dirname( __FILE__ ) . '/csstidy/wordpress-standard.tpl' );
505
506
			// Test for some preg_replace stuff.
507
			{
508
				$prev = $css;
509
				$css = preg_replace( '/\\\\([0-9a-fA-F]{4})/', '\\\\\\\\$1', $css );
510
				// prevent content: '\3434' from turning into '\\3434'.
511
				$css = str_replace( array( '\'\\\\', '"\\\\' ), array( '\'\\', '"\\' ), $css );
512
				if ( $css !== $prev ) {
513
					$warnings[] = 'preg_replace found stuff';
514
				}
515
			}
516
517
			// Some people put weird stuff in their CSS, KSES tends to be greedy.
518
			$css = str_replace( '<=', '&lt;=', $css );
519
520
			// Test for some kses stuff.
521
			{
522
				$prev = $css;
523
				// Why KSES instead of strip_tags?  Who knows?
524
				$css = wp_kses_split( $css, array(), array() );
525
				$css = str_replace( '&gt;', '>', $css ); // kses replaces lone '>' with &gt;
526
				// Why both KSES and strip_tags?  Because we just added some '>'.
527
				$css = strip_tags( $css );
528
529
				if ( $css != $prev ) {
530
					$warnings[] = 'kses found stuff';
531
				}
532
			}
533
534
			// if we're not using a preprocessor.
535 View Code Duplication
			if ( ! $args['preprocessor'] ) {
536
537
				/** This action is documented in modules/custom-css/custom-css.php */
538
				do_action( 'safecss_parse_pre', $csstidy, $css, $args );
539
540
				$csstidy->parse( $css );
541
542
				/** This action is documented in modules/custom-css/custom-css.php */
543
				do_action( 'safecss_parse_post', $csstidy, $warnings, $args );
544
545
				$css = $csstidy->print->plain();
546
			}
547
		}
548
		return $css;
549
	}
550
551
	/**
552
	 * Override $content_width in customizer previews.
553
	 */
554
	public static function preview_content_width() {
555
		global $wp_customize;
556
		if ( ! is_customize_preview() ) {
557
			return;
558
		}
559
560
		$setting = $wp_customize->get_setting( 'jetpack_custom_css[content_width]' );
561
		if ( ! $setting ) {
562
			return;
563
		}
564
565
		$customized_content_width = (int) $setting->post_value();
566
		if ( ! empty( $customized_content_width ) ) {
567
			$GLOBALS['content_width'] = $customized_content_width;
568
		}
569
	}
570
571
	/**
572
	 * Filter the current theme's stylesheet for potentially nullifying it.
573
	 *
574
	 * @param string $current Stylesheet URI for the current theme/child theme.
575
	 *
576
	 * @return mixed|void
577
	 */
578
	static function style_filter( $current ) {
579
		if ( is_admin() ) {
580
			return $current;
581
		} elseif ( self::is_freetrial() && ( ! self::is_preview() || ! current_user_can( 'switch_themes' ) ) ) {
582
			return $current;
583
		} elseif ( self::skip_stylesheet() ) {
584
			/** This filter is documented in modules/custom-css/custom-css.php */
585
			return apply_filters( 'safecss_style_filter_url', plugins_url( 'custom-css/css/blank.css', __FILE__ ) );
586
		}
587
588
		return $current;
589
	}
590
591
	/**
592
	 * Determine whether or not we should have the theme skip its main stylesheet.
593
	 *
594
	 * @return mixed The truthiness of this value determines whether the stylesheet should be skipped.
595
	 */
596
	static function skip_stylesheet() {
597
		/** This filter is documented in modules/custom-css/custom-css.php */
598
		$skip_stylesheet = apply_filters( 'safecss_skip_stylesheet', null );
599
		if ( ! is_null( $skip_stylesheet ) ) {
600
			return $skip_stylesheet;
601
		}
602
603
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
604
		if ( isset( $jetpack_custom_css['replace'] ) ) {
605
			return $jetpack_custom_css['replace'];
606
		}
607
608
		return false;
609
	}
610
611
	/**
612
	 * Override $content_width in customizer previews.
613
	 *
614
	 * Runs on `safecss_skip_stylesheet` filter.
615
	 *
616
	 * @param bool $skip_value Should the stylesheet be skipped.
617
	 *
618
	 * @return null|bool
619
	 */
620
	public static function preview_skip_stylesheet( $skip_value ) {
621
		global $wp_customize;
622
		if ( ! is_customize_preview() ) {
623
			return $skip_value;
624
		}
625
626
		$setting = $wp_customize->get_setting( 'jetpack_custom_css[replace]' );
627
		if ( ! $setting ) {
628
			return $skip_value;
629
		}
630
631
		$customized_replace = $setting->post_value();
632
		if ( null !== $customized_replace ) {
633
			return $customized_replace;
634
		}
635
636
		return $skip_value;
637
	}
638
639
	/**
640
	 * Add Custom CSS section and controls.
641
	 *
642
	 * @param WP_Customize_Manager $wp_customize WP_Customize_Manager instance.
643
	 */
644
	public static function customize_register( $wp_customize ) {
645
646
		/**
647
		 * SETTINGS.
648
		 */
649
650
		$wp_customize->add_setting( 'jetpack_custom_css[preprocessor]', array(
651
			'default' => '',
652
			'transport' => 'postMessage',
653
			'sanitize_callback' => array( __CLASS__, 'sanitize_preprocessor' ),
654
		) );
655
656
		$wp_customize->add_setting( 'jetpack_custom_css[replace]', array(
657
			'default' => false,
658
			'transport' => 'refresh',
659
		) );
660
661
		$wp_customize->add_setting( 'jetpack_custom_css[content_width]', array(
662
			'default' => '',
663
			'transport' => 'refresh',
664
			'sanitize_callback' => array( __CLASS__, 'intval_base10' ),
665
		) );
666
667
		// Add custom sanitization to the core css customizer setting.
668
		foreach ( $wp_customize->settings() as $setting ) {
669
			if ( $setting instanceof WP_Customize_Custom_CSS_Setting ) {
0 ignored issues
show
Bug introduced by
The class WP_Customize_Custom_CSS_Setting does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
670
				add_filter( "customize_sanitize_{$setting->id}", array( __CLASS__, 'sanitize_css_callback' ), 10, 2 );
671
			}
672
		}
673
674
		/**
675
		 * CONTROLS.
676
		 */
677
678
		// Overwrite the Core Control.
679
		$core_custom_css = $wp_customize->get_control( 'custom_css' );
680
		if ( $core_custom_css ) {
681
			$wp_customize->remove_control( 'custom_css' );
682
			$core_custom_css->type = 'jetpackCss';
683
			$wp_customize->add_control( $core_custom_css );
684
		}
685
686
		$wp_customize->selective_refresh->add_partial( 'custom_css', array(
687
			'type'                => 'custom_css',
688
			'selector'            => '#wp-custom-css',
689
			'container_inclusive' => false,
690
			'fallback_refresh'    => false,
691
			'settings'            => array(
692
				'custom_css[' . $wp_customize->get_stylesheet() . ']',
693
				'jetpack_custom_css[preprocessor]',
694
			),
695
			'render_callback' => array( __CLASS__, 'echo_custom_css_partial' ),
696
		) );
697
698
		$wp_customize->add_control( 'wpcom_custom_css_content_width_control', array(
699
			'type'     => 'text',
700
			'label'    => __( 'Media Width', 'jetpack' ),
701
			'section'  => 'custom_css',
702
			'settings' => 'jetpack_custom_css[content_width]',
703
		) );
704
705
		$wp_customize->add_control( 'jetpack_css_mode_control', array(
706
			'type'     => 'checkbox',
707
			'label'    => __( 'Don\'t use the theme\'s original CSS.', 'jetpack' ),
708
			'section'  => 'custom_css',
709
			'settings' => 'jetpack_custom_css[replace]',
710
		) );
711
712
		/**
713
		 * An action to grab on to if another Jetpack Module would like to add its own controls.
714
		 *
715
		 * @module custom-css
716
		 *
717
		 * @since 4.4.2
718
		 *
719
		 * @param $wp_customize The WP_Customize object.
720
		 */
721
		do_action( 'jetpack_custom_css_customizer_controls', $wp_customize );
722
723
		/** This filter is documented in modules/custom-css/custom-css.php */
724
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
725
		if ( ! empty( $preprocessors ) ) {
726
			$preprocessor_choices = array(
727
				'' => __( 'None', 'jetpack' ),
728
			);
729
730
			foreach ( $preprocessors as $preprocessor_key => $processor ) {
731
				$preprocessor_choices[ $preprocessor_key ] = $processor['name'];
732
			}
733
734
			$wp_customize->add_control( 'jetpack_css_preprocessors_control', array(
735
				'type'     => 'select',
736
				'choices'  => $preprocessor_choices,
737
				'label'    => __( 'Preprocessor', 'jetpack' ),
738
				'section'  => 'custom_css',
739
				'settings' => 'jetpack_custom_css[preprocessor]',
740
			) );
741
		}
742
743
	}
744
745
	/**
746
	 * The callback to handle sanitizing the CSS. Takes different arguments, hence the proxy function.
747
	 *
748
	 * @param mixed                $css     Value of the setting.
749
	 * @param WP_Customize_Setting $setting WP_Customize_Setting instance.
750
	 *
751
	 * @return mixed|string
752
	 */
753
	public static function sanitize_css_callback( $css, $setting ) {
0 ignored issues
show
Unused Code introduced by
The parameter $setting is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
754
		global $wp_customize;
755
		return self::sanitize_css( $css, array(
756
			'preprocessor' => $wp_customize->get_setting( 'jetpack_custom_css[preprocessor]' )->value(),
757
		) );
758
	}
759
760
	/**
761
	 * Flesh out for wpcom.
762
	 *
763
	 * @todo
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
764
	 *
765
	 * @return bool
766
	 */
767
	public static function is_freetrial() {
768
		return false;
769
	}
770
771
	/**
772
	 * Flesh out for wpcom.
773
	 *
774
	 * @todo
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
775
	 *
776
	 * @return bool
777
	 */
778
	public static function is_preview() {
779
		return false;
780
	}
781
782
	/**
783
	 * Output the custom css for customize preview.
784
	 *
785
	 * @param string $css Custom CSS content.
786
	 *
787
	 * @return mixed
788
	 */
789
	public static function customize_preview_wp_get_custom_css( $css ) {
790
		global $wp_customize;
791
792
		$preprocessor = $wp_customize->get_setting( 'jetpack_custom_css[preprocessor]' )->value();
793
794
		// If it's empty, just return.
795
		if ( empty( $preprocessor ) ) {
796
			return $css;
797
		}
798
799
		/** This filter is documented in modules/custom-css/custom-css.php */
800
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
801
		if ( isset( $preprocessors[ $preprocessor ] ) ) {
802
			return call_user_func( $preprocessors[ $preprocessor ]['callback'], $css );
803
		}
804
805
		return $css;
806
	}
807
808
	/**
809
	 * Add CSS preprocessing to our CSS if it is supported.
810
	 *
811
	 * @param mixed                $css     Value of the setting.
812
	 * @param WP_Customize_Setting $setting WP_Customize_Setting instance.
813
	 *
814
	 * @return string
815
	 */
816
	public static function customize_value_custom_css( $css, $setting ) {
817
		// Find the current preprocessor.
818
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
819
		if ( isset( $jetpack_custom_css['preprocessor'] ) ) {
820
			$preprocessor = $jetpack_custom_css['preprocessor'];
821
		}
822
823
		// If it's not supported, just return.
824
		/** This filter is documented in modules/custom-css/custom-css.php */
825
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
826
		if ( ! isset( $preprocessors[ $preprocessor ] ) ) {
827
			return $css;
828
		}
829
830
		// Swap it for the `post_content_filtered` instead.
831
		$post = wp_get_custom_css_post( $setting->stylesheet );
832
		if ( $post && ! empty( $post->post_content_filtered ) ) {
833
			$css = $post->post_content_filtered;
834
		}
835
836
		return $css;
837
	}
838
839
	/**
840
	 * Store the original pre-processed CSS in `post_content_filtered`
841
	 * and then store processed CSS in `post_content`.
842
	 *
843
	 * @param array                           $args    Content post args.
844
	 * @param string                          $css     Original CSS being updated.
845
	 * @param WP_Customize_Custom_CSS_Setting $setting Custom CSS Setting.
846
	 *
847
	 * @return mixed
848
	 */
849
	public static function customize_update_custom_css_post_content_args( $args, $css, $setting ) {
0 ignored issues
show
Unused Code introduced by
The parameter $setting is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
850
		// Find the current preprocessor.
851
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
852
		if ( empty( $jetpack_custom_css['preprocessor'] ) ) {
853
			return $args;
854
		}
855
856
		$preprocessor = $jetpack_custom_css['preprocessor'];
857
		/** This filter is documented in modules/custom-css/custom-css.php */
858
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
859
860
		// If it's empty, just return.
861
		if ( empty( $preprocessor ) ) {
862
			return $args;
863
		}
864
865 View Code Duplication
		if ( isset( $preprocessors[ $preprocessor ] ) ) {
866
			$args['post_content_filtered'] = $css;
867
			$args['post_content'] = call_user_func( $preprocessors[ $preprocessor ]['callback'], $css );
868
		}
869
870
		return $args;
871
	}
872
873
	/**
874
	 * Filter to handle the processing of preprocessed css on save.
875
	 *
876
	 * @param array  $args       Custom CSS options.
877
	 * @param string $stylesheet Original CSS to be updated.
878
	 *
879
	 * @return mixed
880
	 */
881
	public static function update_custom_css_data( $args, $stylesheet ) {
0 ignored issues
show
Unused Code introduced by
The parameter $stylesheet is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
882
		// Find the current preprocessor.
883
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
884
		if ( empty( $jetpack_custom_css['preprocessor'] ) ) {
885
			return $args;
886
		}
887
888
		/** This filter is documented in modules/custom-css/custom-css.php */
889
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
890
		$preprocessor = $jetpack_custom_css['preprocessor'];
891
892
		// If we have a preprocessor specified ...
893
		if ( isset( $preprocessors[ $preprocessor ] ) ) {
894
			// And no other preprocessor has run ...
895
			if ( empty( $args['preprocessed'] ) ) {
896
				$args['preprocessed'] = $args['css'];
897
				$args['css'] = call_user_func( $preprocessors[ $preprocessor ]['callback'], $args['css'] );
898
			} else {
899
				trigger_error( 'Jetpack CSS Preprocessor specified, but something else has already modified the argument.', E_USER_WARNING );
900
			}
901
		}
902
903
		return $args;
904
	}
905
906
	/**
907
	 * When on the edit screen, make sure the custom content width
908
	 * setting is applied to the large image size.
909
	 *
910
	 * @param array  $dims    Array of image dimensions (width and height).
911
	 * @param string $size    Size of the resulting image.
912
	 * @param null   $context Context the image is being resized for. `edit` or `display`.
913
	 *
914
	 * @return array
915
	 */
916 View Code Duplication
	static function editor_max_image_size( $dims, $size = 'medium', $context = null ) {
917
		list( $width, $height ) = $dims;
918
919
		if ( 'large' === $size && 'edit' === $context ) {
920
			$width = Jetpack::get_content_width();
921
		}
922
923
		return array( $width, $height );
924
	}
925
926
	/**
927
	 * Override the content_width with a custom value if one is set.
928
	 *
929
	 * @param int $content_width Content Width value to be updated.
930
	 *
931
	 * @return int
932
	 */
933
	static function jetpack_content_width( $content_width ) {
934
		$custom_content_width = 0;
935
936
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
937
		if ( isset( $jetpack_custom_css['content_width'] ) ) {
938
			$custom_content_width = $jetpack_custom_css['content_width'];
939
		}
940
941
		if ( $custom_content_width > 0 ) {
942
			return $custom_content_width;
943
		}
944
945
		return $content_width;
946
	}
947
948
	/**
949
	 * Currently this filter function gets called on
950
	 * 'template_redirect' action and
951
	 * 'admin_init' action
952
	 */
953 View Code Duplication
	static function set_content_width() {
954
		// Don't apply this filter on the Edit CSS page.
955
		if ( isset( $_GET['page'] ) && 'editcss' === $_GET['page'] && is_admin() ) {
956
			return;
957
		}
958
959
		$GLOBALS['content_width'] = Jetpack::get_content_width();
960
	}
961
962
	/**
963
	 * Make sure the preprocessor we're saving is one we know about.
964
	 *
965
	 * @param string $preprocessor The preprocessor to sanitize.
966
	 *
967
	 * @return null|string
968
	 */
969
	public static function sanitize_preprocessor( $preprocessor ) {
970
		/** This filter is documented in modules/custom-css/custom-css.php */
971
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
972
		if ( empty( $preprocessor ) || array_key_exists( $preprocessor, $preprocessors ) ) {
973
			return $preprocessor;
974
		}
975
		return null;
976
	}
977
978
	/**
979
	 * Get the base10 intval.
980
	 *
981
	 * This is used as a setting's sanitize_callback; we can't use just plain
982
	 * intval because the second argument is not what intval() expects.
983
	 *
984
	 * @access public
985
	 *
986
	 * @param mixed $value Number to convert.
987
	 * @return int Integer.
988
	 */
989
	public static function intval_base10( $value ) {
990
		return intval( $value, 10 );
991
	}
992
993
	/**
994
	 * Add a footer action on revision.php to print some customizations for the theme switcher.
995
	 */
996
	public static function load_revision_php() {
997
		add_action( 'admin_footer', array( __CLASS__, 'revision_admin_footer' ) );
998
	}
999
1000
	/**
1001
	 * Print the theme switcher on revision.php and move it into place.
1002
	 */
1003
	public static function revision_admin_footer() {
1004
		$post = get_post();
1005
		if ( 'custom_css' !== $post->post_type ) {
1006
			return;
1007
		}
1008
		$stylesheet = $post->post_title;
1009
		?>
1010
<script type="text/html" id="tmpl-other-themes-switcher">
1011
	<?php self::revisions_switcher_box( $stylesheet ); ?>
1012
</script>
1013
<style>
1014
.other-themes-wrap {
1015
	float: right;
1016
	background-color: #fff;
1017
	-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.1);
1018
	box-shadow: 0 1px 3px rgba(0,0,0,0.1);
1019
	padding: 5px 10px;
1020
	margin-bottom: 10px;
1021
}
1022
.other-themes-wrap label {
1023
	display: block;
1024
	margin-bottom: 10px;
1025
}
1026
.other-themes-wrap select {
1027
	float: left;
1028
	width: 77%;
1029
}
1030
.other-themes-wrap button {
1031
	float: right;
1032
	width: 20%;
1033
}
1034
.revisions {
1035
	clear: both;
1036
}
1037
/* Hide the back-to-post link */
1038
.long-header + a {
1039
	display: none;
1040
}
1041
</style>
1042
<script>
1043
(function($){
1044
	var switcher = $('#tmpl-other-themes-switcher').html(),
1045
		qty = $( switcher ).find('select option').length,
1046
		$switcher;
1047
1048
	if ( qty >= 3 ) {
1049
		$('h1.long-header').before( switcher );
1050
		$switcher = $('.other-themes-wrap');
1051
		$switcher.find('button').on('click', function(e){
1052
			e.preventDefault();
1053
			if ( $switcher.find('select').val() ) {
1054
				window.location.href = $switcher.find('select').val();
1055
			}
1056
		})
1057
	}
1058
})(jQuery);
1059
</script>
1060
		<?php
1061
	}
1062
1063
	/**
1064
	 * The HTML for the theme revision switcher box.
1065
	 *
1066
	 * @param string $stylesheet Stylesheet name.
1067
	 */
1068
	public static function revisions_switcher_box( $stylesheet = '' ) {
1069
		$themes = self::get_all_themes_with_custom_css();
1070
		?>
1071
		<div class="other-themes-wrap">
1072
			<label for="other-themes"><?php esc_html_e( 'Select another theme to view its custom CSS.', 'jetpack' ); ?></label>
1073
			<select id="other-themes">
1074
				<option value=""><?php esc_html_e( 'Select a theme&hellip;', 'jetpack' ); ?></option>
1075
				<?php
1076
				foreach ( $themes as $theme_stylesheet => $data ) {
1077
					$revisions = wp_get_post_revisions( $data['post']->ID, array( 'posts_per_page' => 1 ) );
1078
					if ( ! $revisions ) {
1079
						?>
1080
						<option value="<?php echo esc_url( add_query_arg( 'id', $data['post']->ID, menu_page_url( 'editcss', 0 ) ) ); ?>" <?php disabled( $stylesheet, $theme_stylesheet ); ?>>
1081
							<?php echo esc_html( $data['label'] ); ?>
1082
							<?php printf( esc_html__( '(modified %s ago)', 'jetpack' ), human_time_diff( strtotime( $data['post']->post_modified_gmt ) ) ); ?></option>
1083
						<?php
1084
						continue;
1085
					}
1086
					$revision = array_shift( $revisions );
1087
					?>
1088
					<option value="<?php echo esc_url( get_edit_post_link( $revision->ID ) ); ?>" <?php disabled( $stylesheet, $theme_stylesheet ); ?>>
1089
						<?php echo esc_html( $data['label'] ); ?>
1090
						<?php printf( esc_html__( '(modified %s ago)', 'jetpack' ), human_time_diff( strtotime( $data['post']->post_modified_gmt ) ) ); ?></option>
1091
					<?php
1092
				}
1093
				?>
1094
			</select>
1095
			<button class="button" id="other_theme_custom_css_switcher"><?php esc_html_e( 'Switch', 'jetpack' ); ?></button>
1096
		</div>
1097
		<?php
1098
	}
1099
}
1100
1101
Jetpack_Custom_CSS_Enhancements::add_hooks();
1102
1103 View Code Duplication
if ( ! function_exists( 'safecss_class' ) ) :
1104
	/**
1105
	 * Load in the class only when needed.  Makes lighter load by having one less class in memory.
1106
	 */
1107
	function safecss_class() {
1108
		// Wrapped so we don't need the parent class just to load the plugin.
1109
		if ( class_exists( 'safecss' ) ) {
1110
			return;
1111
		}
1112
1113
		require_once( dirname( __FILE__ ) . '/csstidy/class.csstidy.php' );
1114
1115
		/**
1116
		 * Class safecss
1117
		 */
1118
		class safecss extends csstidy_optimise {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
1119
1120
			/**
1121
			 * Optimises $css after parsing.
1122
			 */
1123
			function postparse() {
1124
1125
				/** This action is documented in modules/custom-css/custom-css.php */
1126
				do_action( 'csstidy_optimize_postparse', $this );
1127
1128
				return parent::postparse();
1129
			}
1130
1131
			/**
1132
			 * Optimises a sub-value.
1133
			 */
1134
			function subvalue() {
1135
1136
				/** This action is documented in modules/custom-css/custom-css.php */
1137
				do_action( 'csstidy_optimize_subvalue', $this );
1138
1139
				return parent::subvalue();
1140
			}
1141
		}
1142
	}
1143
endif;
1144