Completed
Push — upgrade/eslint-5 ( 071910...9f2520 )
by
unknown
07:52
created

get_revisions_url()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 3
nop 1
dl 0
loc 15
rs 9.7666
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
		// Stuff for stripping out the theme's default stylesheet...
35
		add_filter( 'stylesheet_uri', array( __CLASS__, 'style_filter' ) );
36
		add_filter( 'safecss_skip_stylesheet', array( __CLASS__, 'preview_skip_stylesheet' ) );
37
38
		// Stuff for overriding content width...
39
		add_action( 'customize_preview_init', array( __CLASS__, 'preview_content_width' ) );
40
		add_filter( 'jetpack_content_width', array( __CLASS__, 'jetpack_content_width' ) );
41
		add_filter( 'editor_max_image_size', array( __CLASS__, 'editor_max_image_size' ), 10, 3 );
42
		add_action( 'template_redirect', array( __CLASS__, 'set_content_width' ) );
43
		add_action( 'admin_init', array( __CLASS__, 'set_content_width' ) );
44
45
		// Stuff?
46
	}
47
48
	/**
49
	 * Things that we do on init.
50
	 */
51
	public static function init() {
52
		$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...
53
		if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
54
			$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...
55
		}
56
57
		wp_register_style( 'jetpack-codemirror',      plugins_url( 'custom-css/css/codemirror.css', __FILE__ ), array(), '20120905' );
58
		wp_register_style( 'jetpack-customizer-css',  plugins_url( 'custom-css/css/customizer-control.css', __FILE__ ), array(), '20140728' );
59
		wp_register_script( 'jetpack-codemirror',     plugins_url( 'custom-css/js/codemirror.min.js', __FILE__ ), array(), '3.16', true );
60
		$src  = Jetpack::get_file_url_for_environment(
61
			'_inc/build/custom-css/custom-css/js/core-customizer-css.core-4.9.min.js',
62
			'modules/custom-css/custom-css/js/core-customizer-css.core-4.9.js'
63
		);
64
		wp_register_script( 'jetpack-customizer-css', $src, array( 'customize-controls', 'underscore' ), JETPACK__VERSION, true );
65
66
		wp_register_script(
67
			'jetpack-customizer-css-preview',
68
			Jetpack::get_file_url_for_environment(
69
				'_inc/build/custom-css/custom-css/js/core-customizer-css-preview.min.js',
70
				'modules/custom-css/custom-css/js/core-customizer-css-preview.js'
71
			),
72
			array( 'customize-selective-refresh' ),
73
			JETPACK__VERSION,
74
			true
75
		);
76
77
		remove_action( 'wp_head', 'wp_custom_css_cb', 11 ); // 4.7.0 had it at 11, 4.7.1 moved it to 101.
78
		remove_action( 'wp_head', 'wp_custom_css_cb', 101 );
79
		add_action( 'wp_head', array( __CLASS__, 'wp_custom_css_cb' ), 101 );
80
81
		if ( isset( $_GET['custom-css'] ) ) {
82
			self::print_linked_custom_css();
83
		}
84
	}
85
86
	/**
87
	 * Things that we do on init when the Customize Preview is loading.
88
	 */
89
	public static function customize_preview_init() {
90
		add_filter( 'wp_get_custom_css', array( __CLASS__, 'customize_preview_wp_get_custom_css' ) );
91
	}
92
93
	/**
94
	 * Print the current Custom CSS. This is for linking instead of printing directly.
95
	 */
96
	public static function print_linked_custom_css() {
97
		header( 'Content-type: text/css' );
98
		header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + YEAR_IN_SECONDS ) . ' GMT' );
99
		echo wp_get_custom_css();
100
		exit;
101
	}
102
103
	/**
104
	 * Re-map the Edit CSS capability.
105
	 *
106
	 * Core, by default, restricts this to users that have `unfiltered_html` which
107
	 * would make the feature unusable in multi-site by non-super-admins, due to Core
108
	 * not shipping any solid sanitization.
109
	 *
110
	 * We're expanding who can use it, and then conditionally applying CSSTidy
111
	 * sanitization to users that do not have the `unfiltered_html` capability.
112
	 *
113
	 * @param array  $caps Returns the user's actual capabilities.
114
	 * @param string $cap  Capability name.
115
	 *
116
	 * @return array $caps
117
	 */
118
	public static function map_meta_cap( $caps, $cap ) {
119
		if ( 'edit_css' === $cap ) {
120
			$caps = array( 'edit_theme_options' );
121
		}
122
		return $caps;
123
	}
124
125
	/**
126
	 * Handle our admin menu item and legacy page declaration.
127
	 */
128
	public static function admin_menu() {
129
		// Add in our legacy page to support old bookmarks and such.
130
		add_submenu_page( null, __( 'CSS', 'jetpack' ), __( 'Edit CSS', 'jetpack' ), 'edit_theme_options', 'editcss', array( __CLASS__, 'admin_page' ) );
131
132
		// Add in our new page slug that will redirect to the customizer.
133
		$hook = add_theme_page( __( 'CSS', 'jetpack' ), __( 'Edit CSS', 'jetpack' ), 'edit_theme_options', 'editcss-customizer-redirect', array( __CLASS__, 'admin_page' ) );
134
		add_action( "load-{$hook}", array( __CLASS__, 'customizer_redirect' ) );
135
	}
136
137
	/**
138
	 * Handle the redirect for the customizer.  This is necessary because
139
	 * we can't directly add customizer links to the admin menu.
140
	 *
141
	 * There is a core patch in trac that would make this unnecessary.
142
	 *
143
	 * @link https://core.trac.wordpress.org/ticket/39050
144
	 */
145
	public static function customizer_redirect() {
146
		wp_safe_redirect( self::customizer_link( array(
147
			'return_url' => wp_get_referer(),
148
		) ) );
149
		exit;
150
	}
151
152
	/**
153
	 * Shows Preprocessor code in the Revisions screen, and ensures that post_content_filtered
154
	 * is maintained on revisions
155
	 *
156
	 * @param array $fields  Post fields pertinent to revisions.
157
	 * @param array $post    A post array being processed for insertion as a post revision.
158
	 *
159
	 * @return array $fields Modified array to include post_content_filtered.
160
	 */
161
	public static function _wp_post_revision_fields( $fields, $post ) {
162
		// None of the fields in $post are required to be passed in this filter.
163
		if ( ! isset( $post['post_type'], $post['ID'] ) ) {
164
			return $fields;
165
		}
166
167
		// If we're passed in a revision, go get the main post instead.
168
		if ( 'revision' === $post['post_type'] ) {
169
			$main_post_id = wp_is_post_revision( $post['ID'] );
170
			$post = get_post( $main_post_id, ARRAY_A );
171
		}
172
		if ( 'custom_css' === $post['post_type'] ) {
173
			$fields['post_content'] = __( 'CSS', 'jetpack' );
174
			$fields['post_content_filtered'] = __( 'Preprocessor', 'jetpack' );
175
		}
176
		return $fields;
177
	}
178
179
	/**
180
	 * Get the published custom CSS post.
181
	 *
182
	 * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the current theme.
183
	 * @return WP_Post|null
184
	 */
185
	public static function get_css_post( $stylesheet = '' ) {
186
		return wp_get_custom_css_post( $stylesheet );
187
	}
188
189
	/**
190
	 * Override Core's `wp_custom_css_cb` method to provide linking to custom css.
191
	 */
192
	public static function wp_custom_css_cb() {
193
		$styles = wp_get_custom_css();
194
		if ( strlen( $styles ) > 2000 && ! is_customize_preview() ) :
195
			// Add a cache buster to the url.
196
			$url = home_url( '/' );
197
			$url = add_query_arg( 'custom-css', substr( md5( $styles ), -10 ), $url );
198
			?>
199
			<link rel="stylesheet" type="text/css" id="wp-custom-css" href="<?php echo esc_url( $url ); ?>" />
200
		<?php elseif ( $styles || is_customize_preview() ) : ?>
201
			<style type="text/css" id="wp-custom-css">
202
				<?php echo strip_tags( $styles ); // Note that esc_html() cannot be used because `div &gt; span` is not interpreted properly. ?>
203
			</style>
204
		<?php endif;
205
	}
206
207
	/**
208
	 * Get the ID of a Custom CSS post tying to a given stylesheet.
209
	 *
210
	 * @param string $stylesheet Stylesheet name.
211
	 *
212
	 * @return int $post_id Post ID.
213
	 */
214
	public static function post_id( $stylesheet = '' ) {
215
		$post = self::get_css_post( $stylesheet );
216
		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...
217
			return $post->ID;
218
		}
219
		return 0;
220
	}
221
222
	/**
223
	 * Partial for use in the Customizer.
224
	 */
225
	public static function echo_custom_css_partial() {
226
		echo wp_get_custom_css();
227
	}
228
229
	/**
230
	 * Admin page!
231
	 *
232
	 * This currently has two main uses -- firstly to display the css for an inactive
233
	 * theme if there are no revisions attached it to a legacy bug, and secondly to
234
	 * handle folks that have bookmarkes in their browser going to the old page for
235
	 * managing Custom CSS in Jetpack.
236
	 *
237
	 * If we ever add back in a non-Customizer CSS editor, this would be the place.
238
	 */
239
	public static function admin_page() {
240
		$post = null;
241
		$stylesheet = null;
242
		if ( isset( $_GET['id'] ) ) {
243
			$post_id = absint( $_GET['id'] );
244
			$post = get_post( $post_id );
245
			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...
246
				$stylesheet = $post->post_title;
247
			}
248
		}
249
		?>
250
		<div class="wrap">
251
			<?php self::revisions_switcher_box( $stylesheet ); ?>
252
			<h1>
253
				<?php
254
				if ( $post ) {
255
					printf( 'Custom CSS for &#8220;%1$s&#8221;', wp_get_theme( $stylesheet )->Name );
256
				} else {
257
					esc_html_e( 'Custom CSS', 'jetpack' );
258
				}
259
				if ( current_user_can( 'customize' ) ) {
260
					printf(
261
						' <a class="page-title-action hide-if-no-customize" href="%1$s">%2$s</a>',
262
						esc_url( self::customizer_link() ),
263
						esc_html__( 'Manage with Live Preview', 'jetpack' )
264
					);
265
				}
266
				?>
267
			</h1>
268
			<p><?php esc_html_e( 'Custom CSS is now managed in the Customizer.', 'jetpack' ); ?></p>
269
			<?php if ( $post ) : ?>
270
				<div class="revisions">
271
					<h3><?php esc_html_e( 'CSS', 'jetpack' ); ?></h3>
272
					<textarea class="widefat" readonly><?php echo esc_textarea( $post->post_content ); ?></textarea>
273
					<?php if ( $post->post_content_filtered ) : ?>
274
						<h3><?php esc_html_e( 'Preprocessor', 'jetpack' ); ?></h3>
275
						<textarea class="widefat" readonly><?php echo esc_textarea( $post->post_content_filtered ); ?></textarea>
276
					<?php endif; ?>
277
				</div>
278
			<?php endif; ?>
279
		</div>
280
281
		<style>
282
			.other-themes-wrap {
283
				float: right;
284
				background-color: #fff;
285
				-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.1);
286
				box-shadow: 0 1px 3px rgba(0,0,0,0.1);
287
				padding: 5px 10px;
288
				margin-bottom: 10px;
289
			}
290
			.other-themes-wrap label {
291
				display: block;
292
				margin-bottom: 10px;
293
			}
294
			.other-themes-wrap select {
295
				float: left;
296
				width: 77%;
297
			}
298
			.other-themes-wrap button {
299
				float: right;
300
				width: 20%;
301
			}
302
			.revisions {
303
				clear: both;
304
			}
305
			.revisions textarea {
306
				min-height: 300px;
307
				background: #fff;
308
			}
309
		</style>
310
		<script>
311
			(function($){
312
				var $switcher = $('.other-themes-wrap');
313
				$switcher.find('button').on('click', function(e){
314
					e.preventDefault();
315
					if ( $switcher.find('select').val() ) {
316
						window.location.href = $switcher.find('select').val();
317
					}
318
				});
319
			})(jQuery);
320
		</script>
321
		<?php
322
	}
323
324
	/**
325
	 * Build the URL to deep link to the Customizer.
326
	 *
327
	 * You can modify the return url via $args.
328
	 *
329
	 * @param array $args Array of parameters.
330
	 * @return string
331
	 */
332
	public static function customizer_link( $args = array() ) {
333
		$args = wp_parse_args( $args, array(
334
			'return_url' => urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ),
335
		) );
336
337
		return add_query_arg(
338
			array(
339
				array(
340
					'autofocus' => array(
341
						'section' => 'custom_css',
342
					),
343
				),
344
				'return' => $args['return_url'],
345
			),
346
			admin_url( 'customize.php' )
347
		);
348
	}
349
350
	/**
351
	 * Handle the enqueueing and localizing for scripts to be used in the Customizer.
352
	 */
353
	public static function customize_controls_enqueue_scripts() {
354
		wp_enqueue_style( 'jetpack-customizer-css' );
355
		wp_enqueue_script( 'jetpack-customizer-css' );
356
357
		$content_help = __( 'Set a different content width for full size images.', 'jetpack' );
358
		if ( ! empty( $GLOBALS['content_width'] ) ) {
359
			$content_help .= sprintf(
360
				_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' ),
361
				wp_get_theme()->Name,
362
				intval( $GLOBALS['content_width'] )
363
			);
364
		}
365
366
		wp_localize_script( 'jetpack-customizer-css', '_jp_css_settings', array(
367
			/** This filter is documented in modules/custom-css/custom-css.php */
368
			'useRichEditor' => ! jetpack_is_mobile() && apply_filters( 'safecss_use_ace', true ),
369
			'areThereCssRevisions' => self::are_there_css_revisions(),
370
			'revisionsUrl' => self::get_revisions_url(),
371
			'cssHelpUrl' => '//en.support.wordpress.com/custom-design/editing-css/',
372
			'l10n' => array(
373
				'mode'           => __( 'Start Fresh', 'jetpack' ),
374
				'mobile'         => __( 'On Mobile', 'jetpack' ),
375
				'contentWidth'   => $content_help,
376
				'revisions'      => _x( 'See full history', 'Toolbar button to see full CSS revision history', 'jetpack' ),
377
				'css_help_title' => _x( 'Help', 'Toolbar button to get help with custom CSS', 'jetpack' ),
378
			),
379
		));
380
	}
381
382
	/**
383
	 * Check whether there are CSS Revisions for a given theme.
384
	 *
385
	 * Going forward, there should always be, but this was necessitated
386
	 * early on by https://core.trac.wordpress.org/ticket/30854
387
	 *
388
	 * @param string $stylesheet Stylesheet name.
389
	 *
390
	 * @return bool|null|WP_Post
391
	 */
392
	public static function are_there_css_revisions( $stylesheet = '' ) {
393
		$post = wp_get_custom_css_post( $stylesheet );
394
		if ( empty( $post ) ) {
395
			return $post;
396
		}
397
		return (bool) wp_get_post_revisions( $post );
398
	}
399
400
	/**
401
	 * Core doesn't have a function to get the revisions url for a given post ID.
402
	 *
403
	 * @param string $stylesheet Stylesheet name.
404
	 *
405
	 * @return null|string|void
406
	 */
407
	public static function get_revisions_url( $stylesheet = '' ) {
408
		$post = wp_get_custom_css_post( $stylesheet );
409
410
		// If we have any currently saved customizations...
411
		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...
412
			$revisions = wp_get_post_revisions( $post->ID, array( 'posts_per_page' => 1 ) );
413
			if ( empty( $revisions ) || is_wp_error( $revisions ) ) {
414
				return admin_url( 'themes.php?page=editcss' );
415
			}
416
			$revision = reset( $revisions );
417
			return get_edit_post_link( $revision->ID );
418
		}
419
420
		return admin_url( 'themes.php?page=editcss' );
421
	}
422
423
	/**
424
	 * Get a map of all theme names and theme stylesheets for mapping stuff.
425
	 *
426
	 * @return array
427
	 */
428
	public static function get_themes() {
429
		$themes = wp_get_themes( array( 'errors' => null ) );
430
		$all = array();
431
		foreach ( $themes as $theme ) {
432
			$all[ $theme->name ] = $theme->stylesheet;
433
		}
434
		return $all;
435
	}
436
437
	/**
438
	 * When we need to get all themes that have Custom CSS saved.
439
	 *
440
	 * @return array
441
	 */
442
	public static function get_all_themes_with_custom_css() {
443
		$themes = self::get_themes();
444
		$custom_css = get_posts( array(
445
			'post_type'   => 'custom_css',
446
			'post_status' => get_post_stati(),
447
			'number'      => -1,
448
			'order'       => 'DESC',
449
			'orderby'     => 'modified',
450
		) );
451
		$return = array();
452
453
		foreach ( $custom_css as $post ) {
454
			$stylesheet = $post->post_title;
455
			$label      = array_search( $stylesheet, $themes );
456
457
			if ( ! $label ) {
458
				continue;
459
			}
460
461
			$return[ $stylesheet ] = array(
462
				'label' => $label,
463
				'post'  => $post,
464
			);
465
		}
466
467
		return $return;
468
	}
469
470
	/**
471
	 * Handle the enqueueing of scripts for customize previews.
472
	 */
473
	public static function wp_enqueue_scripts() {
474
		if ( is_customize_preview() ) {
475
			wp_enqueue_script( 'jetpack-customizer-css-preview' );
476
			wp_localize_script( 'jetpack-customizer-css-preview', 'jpCustomizerCssPreview', array(
477
				/** This filter is documented in modules/custom-css/custom-css.php */
478
				'preprocessors' => apply_filters( 'jetpack_custom_css_preprocessors', array() ),
479
			));
480
		}
481
	}
482
483
	/**
484
	 * Sanitize the CSS for users without `unfiltered_html`.
485
	 *
486
	 * @param string $css  Input CSS.
487
	 * @param array  $args Array of CSS options.
488
	 *
489
	 * @return mixed|string
490
	 */
491
	public static function sanitize_css( $css, $args = array() ) {
492
		$args = wp_parse_args( $args, array(
493
			'force'        => false,
494
			'preprocessor' => null,
495
		) );
496
497
		if ( $args['force'] || ! current_user_can( 'unfiltered_html' ) ) {
498
499
			$warnings = array();
500
501
			safecss_class();
502
			$csstidy = new csstidy();
503
			$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...
504
505
			$csstidy->set_cfg( 'remove_bslash',              false );
506
			$csstidy->set_cfg( 'compress_colors',            false );
507
			$csstidy->set_cfg( 'compress_font-weight',       false );
508
			$csstidy->set_cfg( 'optimise_shorthands',        0 );
509
			$csstidy->set_cfg( 'remove_last_;',              false );
510
			$csstidy->set_cfg( 'case_properties',            false );
511
			$csstidy->set_cfg( 'discard_invalid_properties', true );
512
			$csstidy->set_cfg( 'css_level',                  'CSS3.0' );
513
			$csstidy->set_cfg( 'preserve_css',               true );
514
			$csstidy->set_cfg( 'template',                   dirname( __FILE__ ) . '/csstidy/wordpress-standard.tpl' );
515
516
			// Test for some preg_replace stuff.
517
			{
518
				$prev = $css;
519
				$css = preg_replace( '/\\\\([0-9a-fA-F]{4})/', '\\\\\\\\$1', $css );
520
				// prevent content: '\3434' from turning into '\\3434'.
521
				$css = str_replace( array( '\'\\\\', '"\\\\' ), array( '\'\\', '"\\' ), $css );
522
				if ( $css !== $prev ) {
523
					$warnings[] = 'preg_replace found stuff';
524
				}
525
			}
526
527
			// Some people put weird stuff in their CSS, KSES tends to be greedy.
528
			$css = str_replace( '<=', '&lt;=', $css );
529
530
			// Test for some kses stuff.
531
			{
532
				$prev = $css;
533
				// Why KSES instead of strip_tags?  Who knows?
534
				$css = wp_kses_split( $css, array(), array() );
535
				$css = str_replace( '&gt;', '>', $css ); // kses replaces lone '>' with &gt;
536
				// Why both KSES and strip_tags?  Because we just added some '>'.
537
				$css = strip_tags( $css );
538
539
				if ( $css != $prev ) {
540
					$warnings[] = 'kses found stuff';
541
				}
542
			}
543
544
			// if we're not using a preprocessor.
545 View Code Duplication
			if ( ! $args['preprocessor'] ) {
546
547
				/** This action is documented in modules/custom-css/custom-css.php */
548
				do_action( 'safecss_parse_pre', $csstidy, $css, $args );
549
550
				$csstidy->parse( $css );
551
552
				/** This action is documented in modules/custom-css/custom-css.php */
553
				do_action( 'safecss_parse_post', $csstidy, $warnings, $args );
554
555
				$css = $csstidy->print->plain();
556
			}
557
		}
558
		return $css;
559
	}
560
561
	/**
562
	 * Override $content_width in customizer previews.
563
	 */
564
	public static function preview_content_width() {
565
		global $wp_customize;
566
		if ( ! is_customize_preview() ) {
567
			return;
568
		}
569
570
		$setting = $wp_customize->get_setting( 'jetpack_custom_css[content_width]' );
571
		if ( ! $setting ) {
572
			return;
573
		}
574
575
		$customized_content_width = (int) $setting->post_value();
576
		if ( ! empty( $customized_content_width ) ) {
577
			$GLOBALS['content_width'] = $customized_content_width;
578
		}
579
	}
580
581
	/**
582
	 * Filter the current theme's stylesheet for potentially nullifying it.
583
	 *
584
	 * @param string $current Stylesheet URI for the current theme/child theme.
585
	 *
586
	 * @return mixed|void
587
	 */
588
	static function style_filter( $current ) {
589
		if ( is_admin() ) {
590
			return $current;
591
		} elseif ( self::is_freetrial() && ( ! self::is_preview() || ! current_user_can( 'switch_themes' ) ) ) {
592
			return $current;
593
		} elseif ( self::skip_stylesheet() ) {
594
			/** This filter is documented in modules/custom-css/custom-css.php */
595
			return apply_filters( 'safecss_style_filter_url', plugins_url( 'custom-css/css/blank.css', __FILE__ ) );
596
		}
597
598
		return $current;
599
	}
600
601
	/**
602
	 * Determine whether or not we should have the theme skip its main stylesheet.
603
	 *
604
	 * @return mixed The truthiness of this value determines whether the stylesheet should be skipped.
605
	 */
606
	static function skip_stylesheet() {
607
		/** This filter is documented in modules/custom-css/custom-css.php */
608
		$skip_stylesheet = apply_filters( 'safecss_skip_stylesheet', null );
609
		if ( ! is_null( $skip_stylesheet ) ) {
610
			return $skip_stylesheet;
611
		}
612
613
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
614
		if ( isset( $jetpack_custom_css['replace'] ) ) {
615
			return $jetpack_custom_css['replace'];
616
		}
617
618
		return false;
619
	}
620
621
	/**
622
	 * Override $content_width in customizer previews.
623
	 *
624
	 * Runs on `safecss_skip_stylesheet` filter.
625
	 *
626
	 * @param bool $skip_value Should the stylesheet be skipped.
627
	 *
628
	 * @return null|bool
629
	 */
630
	public static function preview_skip_stylesheet( $skip_value ) {
631
		global $wp_customize;
632
		if ( ! is_customize_preview() ) {
633
			return $skip_value;
634
		}
635
636
		$setting = $wp_customize->get_setting( 'jetpack_custom_css[replace]' );
637
		if ( ! $setting ) {
638
			return $skip_value;
639
		}
640
641
		$customized_replace = $setting->post_value();
642
		if ( null !== $customized_replace ) {
643
			return $customized_replace;
644
		}
645
646
		return $skip_value;
647
	}
648
649
	/**
650
	 * Add Custom CSS section and controls.
651
	 *
652
	 * @param WP_Customize_Manager $wp_customize WP_Customize_Manager instance.
653
	 */
654
	public static function customize_register( $wp_customize ) {
655
656
		/**
657
		 * SETTINGS.
658
		 */
659
660
		$wp_customize->add_setting( 'jetpack_custom_css[preprocessor]', array(
661
			'default' => '',
662
			'transport' => 'postMessage',
663
			'sanitize_callback' => array( __CLASS__, 'sanitize_preprocessor' ),
664
		) );
665
666
		$wp_customize->add_setting( 'jetpack_custom_css[replace]', array(
667
			'default' => false,
668
			'transport' => 'refresh',
669
		) );
670
671
		$wp_customize->add_setting( 'jetpack_custom_css[content_width]', array(
672
			'default' => '',
673
			'transport' => 'refresh',
674
			'sanitize_callback' => array( __CLASS__, 'intval_base10' ),
675
		) );
676
677
		// Add custom sanitization to the core css customizer setting.
678
		foreach ( $wp_customize->settings() as $setting ) {
679
			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...
680
				add_filter( "customize_sanitize_{$setting->id}", array( __CLASS__, 'sanitize_css_callback' ), 10, 2 );
681
			}
682
		}
683
684
		/**
685
		 * CONTROLS.
686
		 */
687
688
		// Overwrite or Tweak the Core Control.
689
		$core_custom_css = $wp_customize->get_control( 'custom_css' );
690
		if ( $core_custom_css ) {
691
			if ( $core_custom_css instanceof WP_Customize_Code_Editor_Control ) {
0 ignored issues
show
Bug introduced by
The class WP_Customize_Code_Editor_Control 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...
692
				// In WP 4.9, we let the Core CodeMirror control keep running the show, but hook into it to tweak stuff.
693
				$types = array(
694
					'default' => 'text/css',
695
					'less'    => 'text/x-less',
696
					'sass'    => 'text/x-scss',
697
				);
698
				$preprocessor = $wp_customize->get_setting( 'jetpack_custom_css[preprocessor]' )->value();
699
				if ( isset( $types[ $preprocessor ] ) ) {
700
					$core_custom_css->code_type = $types[ $preprocessor ];
701
				}
702
			} else {
703
				// Core < 4.9 Fallback
704
				$core_custom_css->type = 'jetpackCss';
705
			}
706
		}
707
708
		$wp_customize->selective_refresh->add_partial( 'custom_css', array(
709
			'type'                => 'custom_css',
710
			'selector'            => '#wp-custom-css',
711
			'container_inclusive' => false,
712
			'fallback_refresh'    => false,
713
			'settings'            => array(
714
				'custom_css[' . $wp_customize->get_stylesheet() . ']',
715
				'jetpack_custom_css[preprocessor]',
716
			),
717
			'render_callback' => array( __CLASS__, 'echo_custom_css_partial' ),
718
		) );
719
720
		$wp_customize->add_control( 'wpcom_custom_css_content_width_control', array(
721
			'type'     => 'text',
722
			'label'    => __( 'Media Width', 'jetpack' ),
723
			'section'  => 'custom_css',
724
			'settings' => 'jetpack_custom_css[content_width]',
725
		) );
726
727
		$wp_customize->add_control( 'jetpack_css_mode_control', array(
728
			'type'     => 'checkbox',
729
			'label'    => __( 'Don\'t use the theme\'s original CSS.', 'jetpack' ),
730
			'section'  => 'custom_css',
731
			'settings' => 'jetpack_custom_css[replace]',
732
		) );
733
734
		/**
735
		 * An action to grab on to if another Jetpack Module would like to add its own controls.
736
		 *
737
		 * @module custom-css
738
		 *
739
		 * @since 4.4.2
740
		 *
741
		 * @param $wp_customize The WP_Customize object.
742
		 */
743
		do_action( 'jetpack_custom_css_customizer_controls', $wp_customize );
744
745
		/** This filter is documented in modules/custom-css/custom-css.php */
746
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
747
		if ( ! empty( $preprocessors ) ) {
748
			$preprocessor_choices = array(
749
				'' => __( 'None', 'jetpack' ),
750
			);
751
752
			foreach ( $preprocessors as $preprocessor_key => $processor ) {
753
				$preprocessor_choices[ $preprocessor_key ] = $processor['name'];
754
			}
755
756
			$wp_customize->add_control( 'jetpack_css_preprocessors_control', array(
757
				'type'     => 'select',
758
				'choices'  => $preprocessor_choices,
759
				'label'    => __( 'Preprocessor', 'jetpack' ),
760
				'section'  => 'custom_css',
761
				'settings' => 'jetpack_custom_css[preprocessor]',
762
			) );
763
		}
764
765
	}
766
767
	/**
768
	 * The callback to handle sanitizing the CSS. Takes different arguments, hence the proxy function.
769
	 *
770
	 * @param mixed                $css     Value of the setting.
771
	 * @param WP_Customize_Setting $setting WP_Customize_Setting instance.
772
	 *
773
	 * @return mixed|string
774
	 */
775
	public static function sanitize_css_callback( $css, $setting ) {
776
		global $wp_customize;
777
		return self::sanitize_css( $css, array(
778
			'preprocessor' => $wp_customize->get_setting( 'jetpack_custom_css[preprocessor]' )->value(),
779
		) );
780
	}
781
782
	/**
783
	 * Flesh out for wpcom.
784
	 *
785
	 * @todo
786
	 *
787
	 * @return bool
788
	 */
789
	public static function is_freetrial() {
790
		return false;
791
	}
792
793
	/**
794
	 * Flesh out for wpcom.
795
	 *
796
	 * @todo
797
	 *
798
	 * @return bool
799
	 */
800
	public static function is_preview() {
801
		return false;
802
	}
803
804
	/**
805
	 * Output the custom css for customize preview.
806
	 *
807
	 * @param string $css Custom CSS content.
808
	 *
809
	 * @return mixed
810
	 */
811
	public static function customize_preview_wp_get_custom_css( $css ) {
812
		global $wp_customize;
813
814
		$preprocessor = $wp_customize->get_setting( 'jetpack_custom_css[preprocessor]' )->value();
815
816
		// If it's empty, just return.
817
		if ( empty( $preprocessor ) ) {
818
			return $css;
819
		}
820
821
		/** This filter is documented in modules/custom-css/custom-css.php */
822
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
823
		if ( isset( $preprocessors[ $preprocessor ] ) ) {
824
			return call_user_func( $preprocessors[ $preprocessor ]['callback'], $css );
825
		}
826
827
		return $css;
828
	}
829
830
	/**
831
	 * Add CSS preprocessing to our CSS if it is supported.
832
	 *
833
	 * @param mixed                $css     Value of the setting.
834
	 * @param WP_Customize_Setting $setting WP_Customize_Setting instance.
835
	 *
836
	 * @return string
837
	 */
838
	public static function customize_value_custom_css( $css, $setting ) {
839
		// Find the current preprocessor.
840
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
841
		if ( isset( $jetpack_custom_css['preprocessor'] ) ) {
842
			$preprocessor = $jetpack_custom_css['preprocessor'];
843
		}
844
845
		// If it's not supported, just return.
846
		/** This filter is documented in modules/custom-css/custom-css.php */
847
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
848
		if ( ! isset( $preprocessors[ $preprocessor ] ) ) {
849
			return $css;
850
		}
851
852
		// Swap it for the `post_content_filtered` instead.
853
		$post = wp_get_custom_css_post( $setting->stylesheet );
854
		if ( $post && ! empty( $post->post_content_filtered ) ) {
855
			$css = $post->post_content_filtered;
856
		}
857
858
		return $css;
859
	}
860
861
	/**
862
	 * Store the original pre-processed CSS in `post_content_filtered`
863
	 * and then store processed CSS in `post_content`.
864
	 *
865
	 * @param array                           $args    Content post args.
866
	 * @param string                          $css     Original CSS being updated.
867
	 * @param WP_Customize_Custom_CSS_Setting $setting Custom CSS Setting.
868
	 *
869
	 * @return mixed
870
	 */
871
	public static function customize_update_custom_css_post_content_args( $args, $css, $setting ) {
872
		// Find the current preprocessor.
873
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
874
		if ( empty( $jetpack_custom_css['preprocessor'] ) ) {
875
			return $args;
876
		}
877
878
		$preprocessor = $jetpack_custom_css['preprocessor'];
879
		/** This filter is documented in modules/custom-css/custom-css.php */
880
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
881
882
		// If it's empty, just return.
883
		if ( empty( $preprocessor ) ) {
884
			return $args;
885
		}
886
887 View Code Duplication
		if ( isset( $preprocessors[ $preprocessor ] ) ) {
888
			$args['post_content_filtered'] = $css;
889
			$args['post_content'] = call_user_func( $preprocessors[ $preprocessor ]['callback'], $css );
890
		}
891
892
		return $args;
893
	}
894
895
	/**
896
	 * Filter to handle the processing of preprocessed css on save.
897
	 *
898
	 * @param array  $args       Custom CSS options.
899
	 * @param string $stylesheet Original CSS to be updated.
900
	 *
901
	 * @return mixed
902
	 */
903
	public static function update_custom_css_data( $args, $stylesheet ) {
904
		// Find the current preprocessor.
905
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
906
		if ( empty( $jetpack_custom_css['preprocessor'] ) ) {
907
			return $args;
908
		}
909
910
		/** This filter is documented in modules/custom-css/custom-css.php */
911
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
912
		$preprocessor = $jetpack_custom_css['preprocessor'];
913
914
		// If we have a preprocessor specified ...
915
		if ( isset( $preprocessors[ $preprocessor ] ) ) {
916
			// And no other preprocessor has run ...
917
			if ( empty( $args['preprocessed'] ) ) {
918
				$args['preprocessed'] = $args['css'];
919
				$args['css'] = call_user_func( $preprocessors[ $preprocessor ]['callback'], $args['css'] );
920
			} else {
921
				trigger_error( 'Jetpack CSS Preprocessor specified, but something else has already modified the argument.', E_USER_WARNING );
922
			}
923
		}
924
925
		return $args;
926
	}
927
928
	/**
929
	 * When on the edit screen, make sure the custom content width
930
	 * setting is applied to the large image size.
931
	 *
932
	 * @param array  $dims    Array of image dimensions (width and height).
933
	 * @param string $size    Size of the resulting image.
934
	 * @param null   $context Context the image is being resized for. `edit` or `display`.
935
	 *
936
	 * @return array
937
	 */
938 View Code Duplication
	static function editor_max_image_size( $dims, $size = 'medium', $context = null ) {
939
		list( $width, $height ) = $dims;
940
941
		if ( 'large' === $size && 'edit' === $context ) {
942
			$width = Jetpack::get_content_width();
943
		}
944
945
		return array( $width, $height );
946
	}
947
948
	/**
949
	 * Override the content_width with a custom value if one is set.
950
	 *
951
	 * @param int $content_width Content Width value to be updated.
952
	 *
953
	 * @return int
954
	 */
955
	static function jetpack_content_width( $content_width ) {
956
		$custom_content_width = 0;
957
958
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
959
		if ( isset( $jetpack_custom_css['content_width'] ) ) {
960
			$custom_content_width = $jetpack_custom_css['content_width'];
961
		}
962
963
		if ( $custom_content_width > 0 ) {
964
			return $custom_content_width;
965
		}
966
967
		return $content_width;
968
	}
969
970
	/**
971
	 * Currently this filter function gets called on
972
	 * 'template_redirect' action and
973
	 * 'admin_init' action
974
	 */
975 View Code Duplication
	static function set_content_width() {
976
		// Don't apply this filter on the Edit CSS page.
977
		if ( isset( $_GET['page'] ) && 'editcss' === $_GET['page'] && is_admin() ) {
978
			return;
979
		}
980
981
		$GLOBALS['content_width'] = Jetpack::get_content_width();
982
	}
983
984
	/**
985
	 * Make sure the preprocessor we're saving is one we know about.
986
	 *
987
	 * @param string $preprocessor The preprocessor to sanitize.
988
	 *
989
	 * @return null|string
990
	 */
991
	public static function sanitize_preprocessor( $preprocessor ) {
992
		/** This filter is documented in modules/custom-css/custom-css.php */
993
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
994
		if ( empty( $preprocessor ) || array_key_exists( $preprocessor, $preprocessors ) ) {
995
			return $preprocessor;
996
		}
997
		return null;
998
	}
999
1000
	/**
1001
	 * Get the base10 intval.
1002
	 *
1003
	 * This is used as a setting's sanitize_callback; we can't use just plain
1004
	 * intval because the second argument is not what intval() expects.
1005
	 *
1006
	 * @access public
1007
	 *
1008
	 * @param mixed $value Number to convert.
1009
	 * @return int Integer.
1010
	 */
1011
	public static function intval_base10( $value ) {
1012
		return intval( $value, 10 );
1013
	}
1014
1015
	/**
1016
	 * Add a footer action on revision.php to print some customizations for the theme switcher.
1017
	 */
1018
	public static function load_revision_php() {
1019
		add_action( 'admin_footer', array( __CLASS__, 'revision_admin_footer' ) );
1020
	}
1021
1022
	/**
1023
	 * Print the theme switcher on revision.php and move it into place.
1024
	 */
1025
	public static function revision_admin_footer() {
1026
		$post = get_post();
1027
		if ( 'custom_css' !== $post->post_type ) {
1028
			return;
1029
		}
1030
		$stylesheet = $post->post_title;
1031
		?>
1032
<script type="text/html" id="tmpl-other-themes-switcher">
1033
	<?php self::revisions_switcher_box( $stylesheet ); ?>
1034
</script>
1035
<style>
1036
.other-themes-wrap {
1037
	float: right;
1038
	background-color: #fff;
1039
	-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.1);
1040
	box-shadow: 0 1px 3px rgba(0,0,0,0.1);
1041
	padding: 5px 10px;
1042
	margin-bottom: 10px;
1043
}
1044
.other-themes-wrap label {
1045
	display: block;
1046
	margin-bottom: 10px;
1047
}
1048
.other-themes-wrap select {
1049
	float: left;
1050
	width: 77%;
1051
}
1052
.other-themes-wrap button {
1053
	float: right;
1054
	width: 20%;
1055
}
1056
.revisions {
1057
	clear: both;
1058
}
1059
/* Hide the back-to-post link */
1060
.long-header + a {
1061
	display: none;
1062
}
1063
</style>
1064
<script>
1065
(function($){
1066
	var switcher = $('#tmpl-other-themes-switcher').html(),
1067
		qty = $( switcher ).find('select option').length,
1068
		$switcher;
1069
1070
	if ( qty >= 3 ) {
1071
		$('h1.long-header').before( switcher );
1072
		$switcher = $('.other-themes-wrap');
1073
		$switcher.find('button').on('click', function(e){
1074
			e.preventDefault();
1075
			if ( $switcher.find('select').val() ) {
1076
				window.location.href = $switcher.find('select').val();
1077
			}
1078
		})
1079
	}
1080
})(jQuery);
1081
</script>
1082
		<?php
1083
	}
1084
1085
	/**
1086
	 * The HTML for the theme revision switcher box.
1087
	 *
1088
	 * @param string $stylesheet Stylesheet name.
1089
	 */
1090
	public static function revisions_switcher_box( $stylesheet = '' ) {
1091
		$themes = self::get_all_themes_with_custom_css();
1092
		?>
1093
		<div class="other-themes-wrap">
1094
			<label for="other-themes"><?php esc_html_e( 'Select another theme to view its custom CSS.', 'jetpack' ); ?></label>
1095
			<select id="other-themes">
1096
				<option value=""><?php esc_html_e( 'Select a theme&hellip;', 'jetpack' ); ?></option>
1097
				<?php
1098
				foreach ( $themes as $theme_stylesheet => $data ) {
1099
					$revisions = wp_get_post_revisions( $data['post']->ID, array( 'posts_per_page' => 1 ) );
1100
					if ( ! $revisions ) {
1101
						?>
1102
						<option value="<?php echo esc_url( add_query_arg( 'id', $data['post']->ID, menu_page_url( 'editcss', 0 ) ) ); ?>" <?php disabled( $stylesheet, $theme_stylesheet ); ?>>
1103
							<?php echo esc_html( $data['label'] ); ?>
1104
							<?php printf( esc_html__( '(modified %s ago)', 'jetpack' ), human_time_diff( strtotime( $data['post']->post_modified_gmt ) ) ); ?></option>
1105
						<?php
1106
						continue;
1107
					}
1108
					$revision = array_shift( $revisions );
1109
					?>
1110
					<option value="<?php echo esc_url( get_edit_post_link( $revision->ID ) ); ?>" <?php disabled( $stylesheet, $theme_stylesheet ); ?>>
1111
						<?php echo esc_html( $data['label'] ); ?>
1112
						<?php printf( esc_html__( '(modified %s ago)', 'jetpack' ), human_time_diff( strtotime( $data['post']->post_modified_gmt ) ) ); ?></option>
1113
					<?php
1114
				}
1115
				?>
1116
			</select>
1117
			<button class="button" id="other_theme_custom_css_switcher"><?php esc_html_e( 'Switch', 'jetpack' ); ?></button>
1118
		</div>
1119
		<?php
1120
	}
1121
}
1122
1123
Jetpack_Custom_CSS_Enhancements::add_hooks();
1124
1125 View Code Duplication
if ( ! function_exists( 'safecss_class' ) ) :
1126
	/**
1127
	 * Load in the class only when needed.  Makes lighter load by having one less class in memory.
1128
	 */
1129
	function safecss_class() {
1130
		// Wrapped so we don't need the parent class just to load the plugin.
1131
		if ( class_exists( 'safecss' ) ) {
1132
			return;
1133
		}
1134
1135
		require_once( dirname( __FILE__ ) . '/csstidy/class.csstidy.php' );
1136
1137
		/**
1138
		 * Class safecss
1139
		 */
1140
		class safecss extends csstidy_optimise {
1141
1142
			/**
1143
			 * Optimises $css after parsing.
1144
			 */
1145
			function postparse() {
1146
1147
				/** This action is documented in modules/custom-css/custom-css.php */
1148
				do_action( 'csstidy_optimize_postparse', $this );
1149
1150
				return parent::postparse();
1151
			}
1152
1153
			/**
1154
			 * Optimises a sub-value.
1155
			 */
1156
			function subvalue() {
1157
1158
				/** This action is documented in modules/custom-css/custom-css.php */
1159
				do_action( 'csstidy_optimize_subvalue', $this );
1160
1161
				return parent::subvalue();
1162
			}
1163
		}
1164
	}
1165
endif;
1166