Completed
Push — core/custom-css-4.7 ( cbe1bb...6ab2f2 )
by
unknown
21:43 queued 12:06
created

inactive_themes_revision_links()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 27
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 22
nc 4
nop 0
dl 0
loc 27
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Class Jetpack_Custom_CSS_Enhancements
5
 */
6
class Jetpack_Custom_CSS_Enhancements {
7
	public static function add_hooks() {
8
		add_action( 'init', array( __CLASS__, 'init' ) );
9
		add_action( 'admin_menu', array( __CLASS__, 'admin_menu' ) );
10
		add_action( 'customize_controls_enqueue_scripts', array( __CLASS__, 'customize_controls_enqueue_scripts' ) );
11
		add_action( 'customize_register', array( __CLASS__, 'customize_register' ) );
12
		add_filter( 'map_meta_cap', array( __CLASS__, 'map_meta_cap' ), 20, 2 );
13
		add_action( 'customize_preview_init', array( __CLASS__, 'customize_preview_init' ) );
14
		add_filter( '_wp_post_revision_fields', array( __CLASS__, '_wp_post_revision_fields' ), 10, 2 );
15
16
		add_action( 'wp_enqueue_scripts', array( __CLASS__, 'wp_enqueue_scripts' ) );
17
18
		// Handle Sass/LESS
19
		add_filter( 'customize_value_custom_css', array( __CLASS__, 'customize_value_custom_css' ), 10, 2 );
20
		add_filter( 'customize_update_custom_css_post_content_args', array( __CLASS__, 'customize_update_custom_css_post_content_args' ), 10, 3 );
21
		add_filter( 'update_custom_css_data', array( __CLASS__, 'update_custom_css_data' ), 10, 2 );
22
23
		// Handle Sass/LESS
24
		add_filter( 'customize_value_custom_css', array( __CLASS__, 'customize_value_custom_css' ), 10, 2 );
25
		add_filter( 'customize_update_custom_css_post_content_args', array( __CLASS__, 'customize_update_custom_css_post_content_args' ), 10, 3 );
26
27
		// Stuff for stripping out the theme's default stylesheet...
28
		add_filter( 'stylesheet_uri', array( __CLASS__, 'style_filter' ) );
29
		add_filter( 'safecss_skip_stylesheet', array( __CLASS__, 'preview_skip_stylesheet' ) );
30
31
		// Stuff for overriding content width...
32
		add_action( 'customize_preview_init', array( __CLASS__, 'preview_content_width' ) );
33
		add_filter( 'jetpack_content_width', array( __CLASS__, 'jetpack_content_width' ) );
34
		add_filter( 'editor_max_image_size', array( __CLASS__, 'editor_max_image_size' ), 10, 3 );
35
		add_action( 'template_redirect', array( __CLASS__, 'set_content_width' ) );
36
		add_action( 'admin_init', array( __CLASS__, 'set_content_width' ) );
37
38
		// Stuff?
39
	}
40
41
	public static function init() {
42
		$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...
43
		if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
44
			$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...
45
		}
46
47
		wp_register_style( 'jetpack-codemirror',      plugins_url( "custom-css/css/codemirror.css", __FILE__ ), array(), '20120905' );
48
		wp_register_style( 'jetpack-customizer-css',  plugins_url( 'custom-css/css/customizer-control.css', __FILE__ ), array( 'jetpack-codemirror' ), '20140728' );
49
		wp_register_script( 'jetpack-codemirror',     plugins_url( "custom-css/js/codemirror.min.js", __FILE__ ), array(), '3.16', true );
50
		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 );
51
52
		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 );
53
	}
54
55
	public static function customize_preview_init() {
56
		add_filter( 'wp_get_custom_css', array( __CLASS__, 'customize_preview_wp_get_custom_css' ) );
57
	}
58
59
	public static function map_meta_cap( $caps, $cap ) {
60
		if ( 'edit_css' === $cap ) {
61
			$caps = array( 'edit_theme_options' );
62
		}
63
		return $caps;
64
	}
65
66
	public static function admin_menu() {
67
		// Add in our legacy page to support old bookmarks and such.
68
		add_theme_page( __( 'CSS', 'jetpack' ), __( 'Edit CSS', 'jetpack' ), 'edit_theme_options', 'editcss', array( __CLASS__, 'admin_page' ) );
69
70
		// Add in our new page slug that will redirect to the customizer.
71
		$hook = add_theme_page( __( 'CSS', 'jetpack' ), __( 'Edit CSS ⚡', 'jetpack' ), 'edit_theme_options', 'editcss-customizer-redirect', array( __CLASS__, 'admin_page' ) );
72
		add_action( "load-{$hook}", array( __CLASS__, 'customizer_redirect' ) );
73
	}
74
75
	public static function customizer_redirect() {
76
		wp_safe_redirect( self::customizer_link( array(
77
			'return_url' => wp_get_referer(),
78
		) ) );
79
	}
80
81
	public static function prettify_post_revisions() {
82
		add_filter( 'the_title', array( __CLASS__, 'post_title' ), 10, 2 );
83
	}
84
85
	/**
86
	 * Shows Preprocessor code in the Revisions screen, and ensures that post_content_filtered
87
	 * is maintained on revisions
88
	 *
89
	 * @param  array $fields  Post fields pertinent to revisions
90
	 * @return array          Modified array to include post_content_filtered
91
	 */
92
	public static function _wp_post_revision_fields( $fields, $post ) {
93
		// If we're passed in a revision, go get the main post instead.
94
		if ( 'revision' === $post['post_type'] ) {
95
			$main_post_id = wp_is_post_revision( $post['ID'] );
96
			$post = get_post( $main_post_id, ARRAY_A );
97
		}
98
		if ( 'custom_css' === $post['post_type'] ) {
99
			$fields['post_content_filtered'] = __( 'Preprocessor', 'jetpack' );
100
		}
101
		return $fields;
102
	}
103
104
	/**
105
	 * Get the published custom CSS post.
106
	 *
107
	 * @param string $stylesheet Optional. A theme object stylesheet name. Defaults to the current theme.
108
	 *
109
	 * @return WP_Post|null
110
	 */
111
	public static function get_css_post( $stylesheet = '' ) {
112
		return wp_get_custom_css_post( $stylesheet );
113
	}
114
115
	public static function post_id( $stylesheet = '' ) {
116
		$post = self::get_css_post( $stylesheet );
117
		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...
118
			return $post->ID;
119
		}
120
		return 0;
121
	}
122
123
	public static function echo_custom_css_partial() {
124
		echo wp_get_custom_css();
125
	}
126
127
	public static function admin_page() {
128
		?>
129
		<div class="wrap">
130
			<h1>
131
				<?php esc_html_e( 'Custom CSS', 'jetpack' );
132
				if ( current_user_can( 'customize' ) ) {
133
					printf(
134
						' <a class="page-title-action hide-if-no-customize" href="%1$s">%2$s</a>',
135
						esc_url( self::customizer_link() ),
136
						__( 'Manage with Live Preview', 'jetpack' )
137
					);
138
				}
139
				?>
140
			</h1>
141
			<p><?php esc_html_e( 'Custom CSS is now managed in the Customizer.', 'jetpack' ); ?></p>
142
143
			<?php self::inactive_themes_revision_links(); ?>
144
		</div>
145
		<?php
146
	}
147
148
	public static function customizer_link( $args = array() ) {
149
		$args = wp_parse_args( $args, array(
150
			'return_url' => urlencode( wp_unslash( $_SERVER['REQUEST_URI'] ) ),
151
		) );
152
153
		return add_query_arg(
154
			array(
155
				array(
156
					'autofocus' => array(
157
						'section' => 'custom_css'
158
					),
159
				),
160
				'return' => $args['return_url'],
161
			),
162
			admin_url( 'customize.php' )
163
		);
164
	}
165
166
	public static function inactive_themes_revision_links() {
167
		$themes = self::get_all_themes_with_custom_css();
168
		$stylesheet = get_stylesheet();
169
		?>
170
171
		<ul>
172
		<?php foreach ( $themes as $theme_stylesheet => $data ) :
173
			if ( $stylesheet === $theme_stylesheet ) {
174
				continue;
175
			}
176
			$revisions = wp_get_post_revisions( $data['post']->ID, array( 'posts_per_page' => 1 ) );
177
			if ( ! $revisions ) {
178
				?>
179
				<li><a href="<?php echo esc_url( add_query_arg( 'id', $data['post']->ID, menu_page_url( 'editcss', 0 ) ) ); ?>"><?php echo esc_html( $data['label'] ); ?></a>
180
					<?php printf( esc_html__( 'Last modified: %s', 'jetpack' ), get_the_modified_date( '', $data['post'] ) ); ?></li>
181
				<?php
182
				continue;
183
			}
184
			$revision = array_shift( $revisions );
185
			?>
186
			<li><a href="<?php echo esc_url( get_edit_post_link( $revision->ID ) ); ?>"><?php echo esc_html( $data['label'] ); ?></a>
187
				<?php printf( esc_html__( 'Last modified: %s', 'jetpack' ), get_the_modified_date( '', $data['post'] ) ); ?></li>
188
		<?php endforeach; ?>
189
		</ul>
190
191
		<?php
192
	}
193
194
	public static function customize_controls_enqueue_scripts() {
195
		wp_enqueue_style( 'jetpack-customizer-css' );
196
		wp_enqueue_script( 'jetpack-customizer-css' );
197
198
		$content_help = __( 'Set a different content width for full size images.', 'jetpack' );
199
		if ( ! empty( $GLOBALS['content_width'] ) ) {
200
			$content_help .= sprintf( __( ' The default content width for the <strong>%s</strong> theme is %d pixels.', 'jetpack' ), wp_get_theme()->Name, intval( $GLOBALS['content_width'] ) );
201
		}
202
203
		wp_localize_script( 'jetpack-customizer-css', '_jp_css_settings', array(
204
			/** This filter is documented in modules/custom-css/custom-css.php */
205
			'useRichEditor' => ! jetpack_is_mobile() && apply_filters( 'safecss_use_ace', true ),
206
			'areThereCssRevisions' => self::are_there_css_revisions(),
207
			'revisionsUrl' => self::get_revisions_url(),
208
			'cssHelpUrl' => '//en.support.wordpress.com/custom-design/editing-css/',
209
			'l10n' => array(
210
				'mode'           => __( 'Start Fresh', 'jetpack' ),
211
				'mobile'         => __( 'On Mobile', 'jetpack' ),
212
				'contentWidth'   => $content_help,
213
				'revisions'      => __( 'CSS Revisions', 'jetpack' ),
214
				'css_help_title' => __( 'CSS Help', 'jetpack' )
215
			)
216
		));
217
	}
218
219
	public static function are_there_css_revisions( $stylesheet = '' ) {
220
		$post = wp_get_custom_css_post( $stylesheet );
221
		if ( empty( $post ) ) {
222
			return $post;
223
		}
224
		return sizeof( wp_get_post_revisions( $post ) );
225
	}
226
227
	public static function get_revisions_url( $stylesheet = '' ) {
228
		$post = wp_get_custom_css_post( $stylesheet );
229
230
		// If we have any currently saved customizations...
231
		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...
232
			$revisions = wp_get_post_revisions( $post->ID, array( 'posts_per_page' => 1 ) );
233
			$revision = reset( $revisions );
234
			return get_edit_post_link( $revision->ID );
235
		}
236
237
		return admin_url( 'themes.php?page=editcss' );
238
	}
239
240
	public static function get_themes() {
241
		$themes = wp_get_themes( array( 'errors' => null ) );
242
		$all = array();
243
		foreach ( $themes as $theme ) {
244
			$all[ $theme->name ] = $theme->stylesheet;
245
		}
246
		return $all;
247
	}
248
249
	public static function get_all_themes_with_custom_css() {
250
		$themes = self::get_themes();
251
		$custom_css = get_posts( array(
252
			'post_type'   => 'custom_css',
253
			'post_status' => get_post_stati(),
254
			'number'      => -1,
255
			'order'       => 'DESC',
256
			'orderby'     => 'modified',
257
		) );
258
		$return = array();
259
260
		foreach ( $custom_css as $post ) {
261
			$stylesheet = $post->post_title;
262
			$label      = array_search( $stylesheet, $themes );
263
264
			if ( ! $label ) {
265
				continue;
266
			}
267
268
			$return[ $stylesheet ] = array(
269
				'label' => $label,
270
				'post'  => $post,
271
			);
272
		}
273
274
		return $return;
275
	}
276
277
	public static function wp_enqueue_scripts() {
278
		if ( is_customize_preview() ) {
279
			wp_enqueue_script( 'jetpack-customizer-css-preview' );
280
			wp_localize_script( 'jetpack-customizer-css-preview', 'jpCustomizerCssPreview', array(
281
				/** This filter is documented in modules/custom-css/custom-css.php */
282
				'preprocessors' => apply_filters( 'jetpack_custom_css_preprocessors', array() ),
283
			));
284
		}
285
	}
286
287
	public static function sanitize_css( $css, $args = array() ) {
288
		$args = wp_parse_args( $args, array(
289
			'force'        => false,
290
			'preprocessor' => null,
291
		) );
292
293
		if ( $args['force'] || ! current_user_can( 'unfiltered_html' ) ) {
294
295
			$warnings = array();
296
297
			safecss_class();
298
			$csstidy = new csstidy();
299
			$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...
300
301
			$csstidy->set_cfg( 'remove_bslash',              false );
302
			$csstidy->set_cfg( 'compress_colors',            false );
303
			$csstidy->set_cfg( 'compress_font-weight',       false );
304
			$csstidy->set_cfg( 'optimise_shorthands',        0 );
305
			$csstidy->set_cfg( 'remove_last_;',              false );
306
			$csstidy->set_cfg( 'case_properties',            false );
307
			$csstidy->set_cfg( 'discard_invalid_properties', true );
308
			$csstidy->set_cfg( 'css_level',                  'CSS3.0' );
309
			$csstidy->set_cfg( 'preserve_css',               true );
310
			$csstidy->set_cfg( 'template',                   dirname( __FILE__ ) . '/csstidy/wordpress-standard.tpl' );
311
312
			// Test for some preg_replace stuff.
313
			{
314
				$prev = $css;
315
				$css = preg_replace( '/\\\\([0-9a-fA-F]{4})/', '\\\\\\\\$1', $css );
316
				// prevent content: '\3434' from turning into '\\3434'
317
				$css = str_replace( array( '\'\\\\', '"\\\\' ), array( '\'\\', '"\\' ), $css );
318
				if ( $css !== $prev ) {
319
					$warnings[] = 'preg_replace found stuff';
320
				}
321
			}
322
323
			// Some people put weird stuff in their CSS, KSES tends to be greedy
324
			$css = str_replace( '<=', '&lt;=', $css );
325
326
			// Test for some kses stuff.
327
			{
328
				$prev = $css;
329
				// Why KSES instead of strip_tags?  Who knows?
330
				$css = wp_kses_split( $css, array(), array() );
331
				$css = str_replace( '&gt;', '>', $css ); // kses replaces lone '>' with &gt;
332
				// Why both KSES and strip_tags?  Because we just added some '>'.
333
				$css = strip_tags( $css );
334
335
				if ( $css != $prev ) {
336
					$warnings[] = 'kses found stuff';
337
				}
338
			}
339
340
			// if we're not using a preprocessor
341 View Code Duplication
			if ( ! $args['preprocessor'] ) {
342
343
				/**
344
				 * Fires before parsing the css with CSSTidy, but only if
345
				 * the preprocessor is not configured for use.
346
				 *
347
				 * @module custom-css
348
				 *
349
				 * @since 1.7.0
350
				 *
351
				 * @param obj $csstidy The csstidy object.
352
				 * @param string $css Custom CSS.
353
				 * @param array $args Array of custom CSS arguments.
354
				 */
355
				do_action( 'safecss_parse_pre', $csstidy, $css, $args );
356
357
				$csstidy->parse( $css );
358
359
				/**
360
				 * Fires after parsing the css with CSSTidy, but only if
361
				 * the preprocessor is not configured for use.
362
				 *
363
				 * @module custom-css
364
				 *
365
				 * @since 1.7.0
366
				 *
367
				 * @param obj $csstidy The csstidy object.
368
				 * @param array $warnings Array of warnings.
369
				 * @param array $args Array of custom CSS arguments.
370
				 */
371
				do_action( 'safecss_parse_post', $csstidy, $warnings, $args );
372
373
				$css = $csstidy->print->plain();
374
			}
375
		}
376
		return $css;
377
	}
378
379
	/**
380
	 * Override $content_width in customizer previews.
381
	 */
382
	public static function preview_content_width() {
383
		global $wp_customize;
384
		if ( ! is_customize_preview() ) {
385
			return;
386
		}
387
388
		$setting = $wp_customize->get_setting( 'jetpack_custom_css[content_width]' );
389
		if ( ! $setting ) {
390
			return;
391
		}
392
393
		$customized_content_width = (int) $setting->post_value();
394
		if ( ! empty( $customized_content_width ) ) {
395
			$GLOBALS['content_width'] = $customized_content_width;
396
		}
397
	}
398
399
	static function style_filter( $current ) {
400
		if ( is_admin() ) {
401
			return $current;
402
		} elseif ( self::is_freetrial() && ( ! self::is_preview() || ! current_user_can( 'switch_themes' ) ) ) {
403
			return $current;
404
		} elseif ( self::skip_stylesheet() ) {
405
			/** This filter is documented in modules/custom-css/custom-css.php */
406
			return apply_filters( 'safecss_style_filter_url', plugins_url( 'custom-css/css/blank.css', __FILE__ ) );
407
		}
408
409
		return $current;
410
	}
411
412
	/**
413
	 * Determine whether or not we should have the theme skip its main stylesheet.
414
	 *
415
	 * @return mixed The truthiness of this value determines whether the stylesheet should be skipped.
416
	 */
417
	static function skip_stylesheet() {
418
		/** This filter is documented in modules/custom-css/custom-css.php */
419
		$skip_stylesheet = apply_filters( 'safecss_skip_stylesheet', null );
420
		if ( ! is_null( $skip_stylesheet ) ) {
421
			return $skip_stylesheet;
422
		}
423
424
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
425
		if ( isset( $jetpack_custom_css['replace'] ) ) {
426
			return $jetpack_custom_css['replace'];
427
		}
428
429
		return false;
430
	}
431
432
	/**
433
	 * Override $content_width in customizer previews.
434
	 *
435
	 * Runs on `safecss_skip_stylesheet` filter.
436
	 */
437
	public static function preview_skip_stylesheet( $skip_value ) {
438
		global $wp_customize;
439
		if ( ! is_customize_preview() ) {
440
			return $skip_value;
441
		}
442
443
		$setting = $wp_customize->get_setting( 'jetpack_custom_css[replace]' );
444
		if ( ! $setting ) {
445
			return $skip_value;
446
		}
447
448
		$customized_replace = $setting->post_value();
449
		if ( null !== $customized_replace ) {
450
			return $customized_replace;
451
		}
452
453
		return $skip_value;
454
	}
455
456
	/**
457
	 * Add Custom CSS section and controls.
458
	 */
459
	public static function customize_register( $wp_customize ) {
460
461
		// SETTINGS
462
463
		$wp_customize->add_setting( 'jetpack_custom_css[preprocessor]', array(
464
			'default' => '',
465
			'transport' => 'postMessage',
466
			'sanitize_callback' => array( __CLASS__, 'sanitize_preprocessor' ),
467
		) );
468
469
		$wp_customize->add_setting( 'jetpack_custom_css[replace]', array(
470
			'default' => false,
471
			'transport' => 'refresh',
472
		) );
473
474
		$wp_customize->add_setting( 'jetpack_custom_css[content_width]', array(
475
			'default' => '',
476
			'transport' => 'refresh',
477
			'sanitize_callback' => array( __CLASS__, 'intval_base10' ),
478
		) );
479
480
		// Add custom sanitization to the core css customizer setting.
481
		foreach ( $wp_customize->settings() as $setting ) {
482
			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...
483
				add_filter( "customize_sanitize_{$setting->id}", array( __CLASS__, 'sanitize_css_callback' ), 10, 2 );
484
			}
485
		}
486
487
		// CONTROLS
488
489
		// Overwrite the Core Control.
490
		$core_custom_css = $wp_customize->get_control( 'custom_css' );
491
		if ( $core_custom_css ) {
492
			$wp_customize->remove_control( 'custom_css' );
493
			$core_custom_css->type = 'jetpackCss';
494
			$wp_customize->add_control( $core_custom_css );
495
		}
496
497
		$wp_customize->selective_refresh->add_partial( 'custom_css', array(
498
			'type'                => 'custom_css',
499
			'selector'            => '#wp-custom-css',
500
			'container_inclusive' => false,
501
			'fallback_refresh'    => false,
502
			'settings'            => array(
503
				'custom_css[' . $wp_customize->get_stylesheet() . ']',
504
				'jetpack_custom_css[preprocessor]',
505
			),
506
			'render_callback' => array( __CLASS__, 'echo_custom_css_partial' ),
507
		) );
508
509
		$wp_customize->add_control( 'wpcom_custom_css_content_width_control', array(
510
			'type'     => 'text',
511
			'label'    => __( 'Media Width', 'jetpack' ),
512
			'section'  => 'custom_css',
513
			'settings' => 'jetpack_custom_css[content_width]',
514
		) );
515
516
		$wp_customize->add_control( 'jetpack_css_mode_control', array(
517
			'type'     => 'checkbox',
518
			'label'    => __( 'Don\'t use the theme\'s original CSS.', 'jetpack' ),
519
			'section'  => 'custom_css',
520
			'settings' => 'jetpack_custom_css[replace]',
521
		) );
522
523
		/**
524
		 * An action to grab on to if another Jetpack Module would like to add its own controls.
525
		 *
526
		 * @module custom-css
527
		 *
528
		 * @since 4.?.?
529
		 *
530
		 * @param $wp_customize The WP_Customize object.
531
		 */
532
		do_action( 'jetpack_custom_css_customizer_controls', $wp_customize );
533
534
		/** This filter is documented in modules/custom-css/custom-css.php */
535
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
536
		if ( ! empty( $preprocessors ) ) {
537
			$preprocessor_choices = array(
538
				'' => __( 'None', 'jetpack' ),
539
			);
540
541
			foreach ( $preprocessors as $preprocessor_key => $processor ) {
542
				$preprocessor_choices[$preprocessor_key] = $processor['name'];
543
			}
544
545
			$wp_customize->add_control( 'jetpack_css_preprocessors_control', array(
546
				'type'     => 'select',
547
				'choices'  => $preprocessor_choices,
548
				'label'    => __( 'Preprocessor', 'jetpack' ),
549
				'section'  => 'custom_css',
550
				'settings' => 'jetpack_custom_css[preprocessor]',
551
			) );
552
		}
553
554
	}
555
556
	public static function sanitize_css_callback( $css, $setting ) {
0 ignored issues
show
Unused Code introduced by
The parameter $setting is not used and could be removed.

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

Loading history...
557
		global $wp_customize;
558
		return self::sanitize_css( $css, array(
559
			'preprocessor' => $wp_customize->get_setting('jetpack_custom_css[preprocessor]')->value(),
560
		) );
561
	}
562
563
	public static function is_freetrial() {
564
		return false;
565
	}
566
	public static function is_preview() {
567
		return false;
568
	}
569
	public static function is_customizer_preview() {
570
		return false;
571
	}
572
573
	public static function customize_preview_wp_get_custom_css( $css ) {
574
		global $wp_customize;
575
576
		$preprocessor = $wp_customize->get_setting('jetpack_custom_css[preprocessor]')->value();
577
578
		// If it's empty, just return.
579
		if ( empty( $preprocessor ) ) {
580
			return $css;
581
		}
582
583
		/** This filter is documented in modules/custom-css/custom-css.php */
584
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
585
		if ( isset( $preprocessors[ $preprocessor ] ) ) {
586
			return call_user_func( $preprocessors[ $preprocessor ]['callback'], $css );
587
		}
588
589
		return $css;
590
	}
591
592
	public static function customize_value_custom_css( $css, $setting ) {
593
		// Find the current preprocessor
594
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
595
		if ( isset( $jetpack_custom_css['preprocessor'] ) ) {
596
			$preprocessor = $jetpack_custom_css['preprocessor'];
597
		}
598
599
		// If it's not supported, just return.
600
		/** This filter is documented in modules/custom-css/custom-css.php */
601
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
602
		if ( ! isset( $preprocessors[ $preprocessor ] ) ) {
603
			return $css;
604
		}
605
606
		// Swap it for the `post_content_filtered` instead.
607
		$post = wp_get_custom_css_post( $setting->stylesheet );
608
		if ( $post && ! empty( $post->post_content_filtered ) ) {
609
			$css = $post->post_content_filtered;
610
		}
611
612
		return $css;
613
	}
614
615
	/**
616
	 * Soon to be deprecated as the filter moves and new function added.
617
	 */
618
	public static function customize_update_custom_css_post_content_args( $args, $css, $setting ) {
0 ignored issues
show
Unused Code introduced by
The parameter $setting is not used and could be removed.

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

Loading history...
619
		// Find the current preprocessor
620
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
621
		if ( empty( $jetpack_custom_css['preprocessor'] ) ) {
622
			return $args;
623
		}
624
625
		$preprocessor = $jetpack_custom_css['preprocessor'];
626
		/** This filter is documented in modules/custom-css/custom-css.php */
627
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
628
629
		// If it's empty, just return.
630
		if ( empty( $preprocessor ) ) {
631
			return $args;
632
		}
633
634 View Code Duplication
		if ( isset( $preprocessors[ $preprocessor ] ) ) {
635
			$args['post_content_filtered'] = $css;
636
			$args['post_content'] = call_user_func( $preprocessors[ $preprocessor ]['callback'], $css );
637
		}
638
639
		return $args;
640
	}
641
642
	public static function update_custom_css_data( $args, $stylesheet ) {
0 ignored issues
show
Unused Code introduced by
The parameter $stylesheet is not used and could be removed.

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

Loading history...
643
		// Find the current preprocessor
644
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
645
		if ( empty( $jetpack_custom_css['preprocessor'] ) ) {
646
			return $args;
647
		}
648
649
		/** This filter is documented in modules/custom-css/custom-css.php */
650
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
651
		$preprocessor = $jetpack_custom_css['preprocessor'];
652
653
		// If we have a preprocessor specified ...
654
		if ( isset( $preprocessors[ $preprocessor ] ) ) {
655
			// And no other preprocessor has run ...
656
			if ( empty( $args['preprocessed'] ) ) {
657
				$args['preprocessed'] = $args['css'];
658
				$args['css'] = call_user_func( $preprocessors[ $preprocessor ]['callback'], $args['css'] );
659
			} else {
660
				trigger_error( 'Jetpack CSS Preprocessor specified, but something else has already modified the argument.', E_USER_WARNING );
661
			}
662
		}
663
664
		return $args;
665
	}
666
667
	/**
668
	 * When on the edit screen, make sure the custom content width
669
	 * setting is applied to the large image size.
670
	 */
671 View Code Duplication
	static function editor_max_image_size( $dims, $size = 'medium', $context = null ) {
672
		list( $width, $height ) = $dims;
673
674
		if ( 'large' === $size && 'edit' === $context ) {
675
			$width = Jetpack::get_content_width();
676
		}
677
678
		return array( $width, $height );
679
	}
680
681
	/**
682
	 * Override the content_width with a custom value if one is set.
683
	 */
684
	static function jetpack_content_width( $content_width ) {
685
		$custom_content_width = 0;
686
687
		$jetpack_custom_css = get_theme_mod( 'jetpack_custom_css', array() );
688
		if ( isset( $jetpack_custom_css['content_width'] ) ) {
689
			$custom_content_width = $jetpack_custom_css['content_width'];
690
		}
691
692
		if ( $custom_content_width > 0 ) {
693
			return $custom_content_width;
694
		}
695
696
		return $content_width;
697
	}
698
699
	/**
700
	 * Currently this filter function gets called on
701
	 * 'template_redirect' action and
702
	 * 'admin_init' action
703
	 */
704 View Code Duplication
	static function set_content_width(){
705
		// Don't apply this filter on the Edit CSS page
706
		if ( isset( $_GET['page'] ) && 'editcss' === $_GET['page'] && is_admin() ) {
707
			return;
708
		}
709
710
		$GLOBALS['content_width'] = Jetpack::get_content_width();
711
	}
712
713
	/**
714
	 * Make sure the preprocessor we're saving is one we know about.
715
	 *
716
	 * @param $preprocessor The preprocessor to sanitize.
717
	 * @return null|string
718
	 */
719
	public static function sanitize_preprocessor( $preprocessor ) {
720
		/** This filter is documented in modules/custom-css/custom-css.php */
721
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
722
		if ( empty( $preprocessor ) || array_key_exists( $preprocessor, $preprocessors ) ) {
723
			return $preprocessor;
724
		}
725
		return null;
726
	}
727
728
	/**
729
	 * Get the base10 intval.
730
	 *
731
	 * This is used as a setting's sanitize_callback; we can't use just plain
732
	 * intval because the second argument is not what intval() expects.
733
	 *
734
	 * @access public
735
	 *
736
	 * @param mixed $value Number to convert.
737
	 * @return int Integer.
738
	 */
739
	public static function intval_base10( $value ) {
740
		return intval( $value, 10 );
741
	}
742
}
743
744
Jetpack_Custom_CSS_Enhancements::add_hooks();
745
746 View Code Duplication
function safecss_class() {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
747
	// Wrapped so we don't need the parent class just to load the plugin
748
	if ( class_exists('safecss') ) {
749
		return;
750
	}
751
752
	require_once( dirname( __FILE__ ) . '/csstidy/class.csstidy.php' );
753
754
	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...
755
756
		function postparse() {
757
758
			/**
759
			 * Fires after parsing the css.
760
			 *
761
			 * @module custom-css
762
			 *
763
			 * @since 1.8.0
764
			 *
765
			 * @param obj $this CSSTidy object.
766
			 */
767
			do_action( 'csstidy_optimize_postparse', $this );
768
769
			return parent::postparse();
770
		}
771
772
		function subvalue() {
773
774
			/**
775
			 * Fires before optimizing the Custom CSS subvalue.
776
			 *
777
			 * @module custom-css
778
			 *
779
			 * @since 1.8.0
780
			 *
781
			 * @param obj $this CSSTidy object.
782
			 **/
783
			do_action( 'csstidy_optimize_subvalue', $this );
784
785
			return parent::subvalue();
786
		}
787
	}
788
}
789