Completed
Push — add/changelog-55 ( 8beac4...406ec3 )
by Jeremy
15:59 queued 07:35
created

Jetpack_Custom_CSS_Enhancements::init()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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