Completed
Push — add/feature-rollout ( 16c199...2484fa )
by
unknown
10:53
created

custom-css.php ➔ safecss_class()   B

Complexity

Conditions 1
Paths 2

Size

Total Lines 42
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 2
nop 0
dl 0
loc 42
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
class Jetpack_Custom_CSS {
4
	static function init() {
5
		add_action( 'switch_theme', array( __CLASS__, 'reset' ) );
6
		add_action( 'wp_restore_post_revision', array( __CLASS__, 'restore_revision' ), 10, 2 );
7
8
		// Save revisions for posts of type safecss.
9
		add_action( 'load-revision.php', array( __CLASS__, 'add_revision_redirect' ) );
10
11
		// Override the edit link, the default link causes a redirect loop
12
		add_filter( 'get_edit_post_link', array( __CLASS__, 'revision_post_link' ), 10, 3 );
13
14
		// Overwrite the content width global variable if one is set in the custom css
15
		add_action( 'template_redirect', array( __CLASS__, 'set_content_width' ) );
16
		add_action( 'admin_init', array( __CLASS__, 'set_content_width' ) );
17
18
		if ( ! is_admin() )
19
			add_filter( 'stylesheet_uri', array( __CLASS__, 'style_filter' ) );
20
21
		define(
22
			'SAFECSS_USE_ACE',
23
			! jetpack_is_mobile() &&
24
			! Jetpack_User_Agent_Info::is_ipad() &&
25
			/**
26
			 * Should the Custom CSS module use ACE to process CSS.
27
			 * @see http://ace.c9.io/
28
			 *
29
			 * @module custom-css
30
			 *
31
			 * @since 1.7.0
32
			 *
33
			 * @param bool true Use ACE to process the Custom CSS. Default to true.
34
			 */
35
			apply_filters( 'safecss_use_ace', true )
36
		);
37
38
		// Register safecss as a custom post_type
39
		// Explicit capability definitions are largely unnecessary because the posts are manipulated in code via an options page, managing CSS revisions does check the capabilities, so let's ensure that the proper caps are checked.
40
		register_post_type( 'safecss', array(
41
	//		These are the defaults
42
	//		'exclude_from_search' => true,
43
	//		'public' => false,
44
	//		'publicly_queryable' => false,
45
	//		'show_ui' => false,
46
			'supports' => array( 'revisions' ),
47
			'label' => 'Custom CSS',
48
			'can_export' => false,
49
			'rewrite' => false,
50
			'capabilities' => array(
51
				'edit_post' => 'edit_theme_options',
52
				'read_post' => 'read',
53
				'delete_post' => 'edit_theme_options',
54
				'edit_posts' => 'edit_theme_options',
55
				'edit_others_posts' => 'edit_theme_options',
56
				'publish_posts' => 'edit_theme_options',
57
				'read_private_posts' => 'read'
58
			)
59
		) );
60
61
		// Short-circuit WP if this is a CSS stylesheet request
62
		if ( isset( $_GET['custom-css'] ) ) {
63
			header( 'Content-Type: text/css', true, 200 );
64
			header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + 31536000) . ' GMT' ); // 1 year
65
			Jetpack_Custom_CSS::print_css();
66
			exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method init() 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...
67
		}
68
69
		add_action( 'admin_enqueue_scripts', array( 'Jetpack_Custom_CSS', 'enqueue_scripts' ) );
70
71
		if ( isset( $_GET['page'] ) && 'editcss' == $_GET['page'] && is_admin() ) {
72
			// Do migration routine if necessary
73
			Jetpack_Custom_CSS::upgrade();
74
75
			/**
76
			 * Allows additional work when migrating safecss from wp_options to wp_post.
77
			 *
78
			 * @module custom-css
79
			 *
80
			 * @since 1.7.0
81
			 */
82
			do_action( 'safecss_migrate_post' );
83
		}
84
85
		/**
86
		 * Never embed the style in the head on wpcom.
87
		 * Yes, this filter should be added to an unsynced file on wpcom, but
88
		 * there is no good syntactically-correct location to put it yet.
89
		 * @link https://github.com/Automattic/jetpack/commit/a1be114e9179f64d147124727a58e2cf76c7e5a1#commitcomment-7763921
90
		 */
91
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
92
			add_filter( 'safecss_embed_style', '__return_false' );
93
		} else {
94
			add_filter( 'safecss_embed_style', array( 'Jetpack_Custom_CSS', 'should_we_inline_custom_css' ), 10, 2 );
95
		}
96
97
		add_action( 'wp_head', array( 'Jetpack_Custom_CSS', 'link_tag' ), 101 );
98
99
		add_filter( 'jetpack_content_width', array( 'Jetpack_Custom_CSS', 'jetpack_content_width' ) );
100
		add_filter( 'editor_max_image_size', array( 'Jetpack_Custom_CSS', 'editor_max_image_size' ), 10, 3 );
101
102
		if ( !current_user_can( 'switch_themes' ) && !is_super_admin() )
103
			return;
104
105
		add_action( 'admin_menu', array( 'Jetpack_Custom_CSS', 'menu' ) );
106
107
		if ( isset( $_POST['safecss'] ) && false == strstr( $_SERVER[ 'REQUEST_URI' ], 'options.php' ) ) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing strstr($_SERVER['REQUEST_URI'], 'options.php') of type string to the boolean false. If you are specifically checking for an empty string, consider using the more explicit === '' instead.
Loading history...
108
			check_admin_referer( 'safecss' );
109
110
			$save_result = self::save( array(
111
				'css' => stripslashes( $_POST['safecss'] ),
112
				'is_preview' => isset( $_POST['action'] ) && $_POST['action'] == 'preview',
113
				'preprocessor' => isset( $_POST['custom_css_preprocessor'] ) ? $_POST['custom_css_preprocessor'] : '',
114
				'add_to_existing' => isset( $_POST['add_to_existing'] ) ? $_POST['add_to_existing'] == 'true' : true,
115
				'content_width' => isset( $_POST['custom_content_width'] ) ? $_POST['custom_content_width'] : false,
116
			) );
117
118
			if ( $_POST['action'] == 'preview' ) {
119
				wp_safe_redirect( add_query_arg( 'csspreview', 'true', get_option( 'home' ) ) );
120
				exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method init() 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...
121
			}
122
123
			if ( $save_result )
124
				add_action( 'admin_notices', array( 'Jetpack_Custom_CSS', 'saved_message' ) );
125
		}
126
127
		// Prevent content filters running on CSS when restoring revisions
128
		if ( isset( $_REQUEST[ 'action' ] ) && 'restore' === $_REQUEST[ 'action' ] && false !== strstr( $_SERVER[ 'REQUEST_URI' ], 'revision.php' ) ) {
129
			$parent_post = get_post( wp_get_post_parent_id( intval( $_REQUEST[ 'revision' ] ) ) );
130
			if ( $parent_post && ! is_wp_error( $parent_post ) && 'safecss' === $parent_post->post_type ) {
131
				// Remove wp_filter_post_kses, this causes CSS escaping issues
132
				remove_filter( 'content_save_pre', 'wp_filter_post_kses' );
133
				remove_filter( 'content_filtered_save_pre', 'wp_filter_post_kses' );
134
				remove_all_filters( 'content_save_pre' );
135
			}
136
		}
137
138
		// Modify all internal links so that preview state persists
139
		if ( Jetpack_Custom_CSS::is_preview() )
140
			ob_start( array( 'Jetpack_Custom_CSS', 'buffer' ) );
141
	}
142
143
	/**
144
	 * Save new custom CSS. This should be the entry point for any third-party code using Jetpack_Custom_CSS
145
	 * to save CSS.
146
	 *
147
	 * @param array $args Array of arguments:
148
	 *        string $css The CSS (or LESS or Sass)
149
	 *        bool $is_preview Whether this CSS is preview or published
150
	 *        string preprocessor Which CSS preprocessor to use
151
	 *        bool $add_to_existing Whether this CSS replaces the theme's CSS or supplements it.
152
	 *        int $content_width A custom $content_width to go along with this CSS.
153
	 * @return int The post ID of the saved Custom CSS post.
154
	 */
155
	public static function save( $args = array() ) {
156
		$defaults = array(
157
			'css' => '',
158
			'is_preview' => false,
159
			'preprocessor' => '',
160
			'add_to_existing' => true,
161
			'content_width' => false,
162
		);
163
164
		$args = wp_parse_args( $args, $defaults );
165
166
		if ( $args['content_width'] && intval( $args['content_width']) > 0 && ( ! isset( $GLOBALS['content_width'] ) || $args['content_width'] != $GLOBALS['content_width'] ) )
167
			$args['content_width'] = intval( $args['content_width'] );
168
		else
169
			$args['content_width'] = false;
170
171
		// Remove wp_filter_post_kses, this causes CSS escaping issues
172
		remove_filter( 'content_save_pre', 'wp_filter_post_kses' );
173
		remove_filter( 'content_filtered_save_pre', 'wp_filter_post_kses' );
174
		remove_all_filters( 'content_save_pre' );
175
176
		/**
177
		 * Fires prior to saving custom css values. Necessitated because the
178
		 * core WordPress save_pre filters were removed:
179
		 * - content_save_pre
180
		 * - content_filtered_save_pre
181
		 *
182
		 * @module custom-css
183
		 *
184
		 * @since 1.7.0
185
		 *
186
		 * @param array $args {
187
		 * Array of custom CSS arguments.
188
		 * 	@type string $css The CSS (or LESS or Sass).
189
		 * 	@type bool $is_preview Whether this CSS is preview or published.
190
		 * 	@type string preprocessor Which CSS preprocessor to use.
191
		 * 	@type bool $add_to_existing Whether this CSS replaces the theme's CSS or supplements it.
192
		 * 	@type int $content_width A custom $content_width to go along with this CSS.
193
		 * }
194
		 */
195
		do_action( 'safecss_save_pre', $args );
196
197
		$warnings = array();
198
199
		safecss_class();
200
		$csstidy = new csstidy();
201
		$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...
202
203
		$csstidy->set_cfg( 'remove_bslash',              false );
204
		$csstidy->set_cfg( 'compress_colors',            false );
205
		$csstidy->set_cfg( 'compress_font-weight',       false );
206
		$csstidy->set_cfg( 'optimise_shorthands',        0 );
207
		$csstidy->set_cfg( 'remove_last_;',              false );
208
		$csstidy->set_cfg( 'case_properties',            false );
209
		$csstidy->set_cfg( 'discard_invalid_properties', true );
210
		$csstidy->set_cfg( 'css_level',                  'CSS3.0' );
211
		$csstidy->set_cfg( 'preserve_css',               true );
212
		$csstidy->set_cfg( 'template',                   dirname( __FILE__ ) . '/csstidy/wordpress-standard.tpl' );
213
214
		$css = $orig = $args['css'];
0 ignored issues
show
Unused Code introduced by
$orig 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...
215
216
		$css = preg_replace( '/\\\\([0-9a-fA-F]{4})/', '\\\\\\\\$1', $prev = $css );
217
		// prevent content: '\3434' from turning into '\\3434'
218
		$css = str_replace( array( '\'\\\\', '"\\\\' ), array( '\'\\', '"\\' ), $css );
219
220
		if ( $css != $prev )
221
			$warnings[] = 'preg_replace found stuff';
222
223
		// Some people put weird stuff in their CSS, KSES tends to be greedy
224
		$css = str_replace( '<=', '&lt;=', $css );
225
		// Why KSES instead of strip_tags?  Who knows?
226
		$css = wp_kses_split( $prev = $css, array(), array() );
227
		$css = str_replace( '&gt;', '>', $css ); // kses replaces lone '>' with &gt;
228
		// Why both KSES and strip_tags?  Because we just added some '>'.
229
		$css = strip_tags( $css );
230
231
		if ( $css != $prev )
232
			$warnings[] = 'kses found stuff';
233
234
		// if we're not using a preprocessor
235 View Code Duplication
		if ( ! $args['preprocessor'] ) {
236
237
			/**
238
			 * Fires before parsing the css with CSSTidy, but only if
239
			 * the preprocessor is not configured for use.
240
			 *
241
			 * @module custom-css
242
			 *
243
			 * @since 1.7.0
244
			 *
245
			 * @param obj $csstidy The csstidy object.
246
			 * @param string $css Custom CSS.
247
			 * @param array $args Array of custom CSS arguments.
248
			 */
249
			do_action( 'safecss_parse_pre', $csstidy, $css, $args );
250
251
			$csstidy->parse( $css );
252
253
			/**
254
			 * Fires after parsing the css with CSSTidy, but only if
255
			 * the preprocessor is not cinfigured for use.
256
			 *
257
			 * @module custom-css
258
			 *
259
			 * @since 1.7.0
260
			 *
261
			 * @param obj $csstidy The csstidy object.
262
			 * @param array $warnings Array of warnings.
263
			 * @param array $args Array of custom CSS arguments.
264
			 */
265
			do_action( 'safecss_parse_post', $csstidy, $warnings, $args );
266
267
			$css = $csstidy->print->plain();
268
		}
269
270
		if ( $args['add_to_existing'] )
271
			$add_to_existing = 'yes';
272
		else
273
			$add_to_existing = 'no';
274
275
		if ( $args['is_preview'] || Jetpack_Custom_CSS::is_freetrial() ) {
276
			// Save the CSS
277
			$safecss_revision_id = Jetpack_Custom_CSS::save_revision( $css, true, $args['preprocessor'] );
278
279
			// Cache Buster
280
			update_option( 'safecss_preview_rev', intval( get_option( 'safecss_preview_rev' ) ) + 1);
281
282
			update_metadata( 'post', $safecss_revision_id, 'custom_css_add', $add_to_existing );
283
			update_metadata( 'post', $safecss_revision_id, 'content_width', $args['content_width'] );
284
			update_metadata( 'post', $safecss_revision_id, 'custom_css_preprocessor', $args['preprocessor'] );
285
286
			delete_option( 'safecss_add' );
287
			delete_option( 'safecss_content_width' );
288
289
			if ( $args['is_preview'] ) {
290
				return $safecss_revision_id;
291
			}
292
293
			/**
294
			 * Fires after saving Custom CSS.
295
			 *
296
			 * @module custom-css
297
			 *
298
			 * @since 1.7.0
299
			 */
300
			do_action( 'safecss_save_preview_post' );
301
		}
302
303
		// Save the CSS
304
		$safecss_post_id = Jetpack_Custom_CSS::save_revision( $css, false, $args['preprocessor'] );
305
306
		$safecss_post_revision = Jetpack_Custom_CSS::get_current_revision();
307
308
		update_option( 'safecss_rev', intval( get_option( 'safecss_rev' ) ) + 1 );
309
310
		update_post_meta( $safecss_post_id, 'custom_css_add', $add_to_existing );
311
		update_post_meta( $safecss_post_id, 'content_width', $args['content_width'] );
312
		update_post_meta( $safecss_post_id, 'custom_css_preprocessor', $args['preprocessor'] );
313
314
		delete_option( 'safecss_add' );
315
		delete_option( 'safecss_content_width' );
316
317
		update_metadata( 'post', $safecss_post_revision['ID'], 'custom_css_add', $add_to_existing );
318
		update_metadata( 'post', $safecss_post_revision['ID'], 'content_width', $args['content_width'] );
319
		update_metadata( 'post', $safecss_post_revision['ID'], 'custom_css_preprocessor', $args['preprocessor'] );
320
321
		delete_option( 'safecss_preview_add' );
322
323
		return $safecss_post_id;
324
	}
325
326
	/**
327
	 * Get the published custom CSS post.
328
	 *
329
	 * @return array
330
	 */
331
	static function get_post() {
332
		$custom_css_post_id = Jetpack_Custom_CSS::post_id();
333
334
		if ( $custom_css_post_id )
335
			return get_post( $custom_css_post_id, ARRAY_A );
336
337
		return array();
338
	}
339
340
	/**
341
	 * Get the post ID of the published custom CSS post.
342
	 *
343
	 * @return int|bool The post ID if it exists; false otherwise.
344
	 */
345 View Code Duplication
	static function post_id() {
346
		/**
347
		 * Filter the ID of the post where Custom CSS is stored, before the ID is retrieved.
348
		 *
349
		 * If the callback function returns a non-null value, then post_id() will immediately
350
		 * return that value, instead of retrieving the normal post ID.
351
		 *
352
		 * @module custom-css
353
		 *
354
		 * @since 3.8.1
355
		 *
356
		 * @param null null The ID to return instead of the normal ID.
357
		 */
358
		$custom_css_post_id = apply_filters( 'jetpack_custom_css_pre_post_id', null );
359
		if ( ! is_null( $custom_css_post_id ) ) {
360
			return $custom_css_post_id;
361
		}
362
363
		$custom_css_post_id = wp_cache_get( 'custom_css_post_id' );
364
365
		if ( false === $custom_css_post_id ) {
366
			$custom_css_posts = get_posts( array(
367
				'posts_per_page' => 1,
368
				'post_type' => 'safecss',
369
				'post_status' => 'publish',
370
				'orderby' => 'date',
371
				'order' => 'DESC'
372
			) );
373
374
			if ( count( $custom_css_posts ) > 0 )
375
				$custom_css_post_id = $custom_css_posts[0]->ID;
376
			else
377
				$custom_css_post_id = 0;
378
379
			// Save post_id=0 to note that no safecss post exists.
380
			wp_cache_set( 'custom_css_post_id', $custom_css_post_id );
381
		}
382
383
		if ( ! $custom_css_post_id )
384
			return false;
385
386
		return $custom_css_post_id;
387
	}
388
389
	/**
390
	 * Get the current revision of the original safecss record
391
	 *
392
	 * @return object
393
	 */
394
	static function get_current_revision() {
395
		$safecss_post = Jetpack_Custom_CSS::get_post();
396
397
		if ( empty( $safecss_post ) ) {
398
			return false;
399
		}
400
401
		$revisions = wp_get_post_revisions( $safecss_post['ID'], array( 'posts_per_page' => 1, 'orderby' => 'date', 'order' => 'DESC' ) );
402
403
		// Empty array if no revisions exist
404
		if ( empty( $revisions ) ) {
405
			// Return original post
406
			return $safecss_post;
407
		} else {
408
			// Return the first entry in $revisions, this will be the current revision
409
			$current_revision = get_object_vars( array_shift( $revisions ) );
410
			return $current_revision;
411
		}
412
	}
413
414
	/**
415
	 * Save new revision of CSS
416
	 * Checks to see if content was modified before really saving
417
	 *
418
	 * @param string $css
419
	 * @param bool $is_preview
420
	 * @return bool|int If nothing was saved, returns false. If a post
421
	 *                  or revision was saved, returns the post ID.
422
	 */
423
	static function save_revision( $css, $is_preview = false, $preprocessor = '' ) {
424
		$safecss_post = Jetpack_Custom_CSS::get_post();
425
426
		$compressed_css = Jetpack_Custom_CSS::minify( $css, $preprocessor );
427
428
		// If null, there was no original safecss record, so create one
429
		if ( null == $safecss_post ) {
430
			if ( ! $css )
431
				return false;
432
433
			$post = array();
434
			$post['post_content'] = wp_slash( $css );
435
			$post['post_title'] = 'safecss';
436
			$post['post_status'] = 'publish';
437
			$post['post_type'] = 'safecss';
438
			$post['post_content_filtered'] = wp_slash( $compressed_css );
439
440
			// Set excerpt to current theme, for display in revisions list
441 View Code Duplication
			if ( function_exists( 'wp_get_theme' ) ) {
442
				$current_theme = wp_get_theme();
443
				$post['post_excerpt'] = $current_theme->Name;
444
			}
445
			else {
446
				$post['post_excerpt'] = get_current_theme();
447
			}
448
449
			// Insert the CSS into wp_posts
450
			$post_id = wp_insert_post( $post );
451
			wp_cache_set( 'custom_css_post_id', $post_id );
452
			return $post_id;
453
		}
454
455
		// Update CSS in post array with new value passed to this function
456
		$safecss_post['post_content'] = $css;
457
		$safecss_post['post_content_filtered'] = $compressed_css;
458
459
		// Set excerpt to current theme, for display in revisions list
460 View Code Duplication
		if ( function_exists( 'wp_get_theme' ) ) {
461
			$current_theme = wp_get_theme();
462
			$safecss_post['post_excerpt'] = $current_theme->Name;
463
		}
464
		else {
465
			$safecss_post['post_excerpt'] = get_current_theme();
466
		}
467
468
		// Don't carry over last revision's timestamps, otherwise revisions all have matching timestamps
469
		unset( $safecss_post['post_date'] );
470
		unset( $safecss_post['post_date_gmt'] );
471
		unset( $safecss_post['post_modified'] );
472
		unset( $safecss_post['post_modified_gmt'] );
473
474
		// Do not update post if we are only saving a preview
475
		if ( false === $is_preview ) {
476
			$safecss_post['post_content'] = wp_slash( $safecss_post['post_content'] );
477
			$safecss_post['post_content_filtered'] = wp_slash( $safecss_post['post_content_filtered'] );
478
			$post_id = wp_update_post( $safecss_post );
479
			wp_cache_set( 'custom_css_post_id', $post_id );
480
			return $post_id;
481
		}
482
		else if ( ! defined( 'DOING_MIGRATE' ) ) {
483
			return _wp_put_post_revision( $safecss_post );
484
		}
485
	}
486
487
	static function skip_stylesheet() {
488
		/**
489
		 * Prevent the Custom CSS stylesheet from being enqueued.
490
		 *
491
		 * @module custom-css
492
		 *
493
		 * @since 2.2.1
494
		 *
495
		 * @param null Should the stylesheet be skipped. Default to null. Anything else will force the stylesheet to be skipped.
496
		 */
497
		$skip_stylesheet = apply_filters( 'safecss_skip_stylesheet', null );
498
499
		if ( null !== $skip_stylesheet ) {
500
			return $skip_stylesheet;
501
		} elseif ( Jetpack_Custom_CSS::is_customizer_preview() ) {
502
			return false;
503
		} else {
504
			if ( Jetpack_Custom_CSS::is_preview() ) {
505
				$safecss_post = Jetpack_Custom_CSS::get_current_revision();
506
507
				if ( $safecss_post )
508
					return (bool) ( get_post_meta( $safecss_post['ID'], 'custom_css_add', true ) == 'no' );
509
				else
510
					return (bool) ( get_option( 'safecss_preview_add' ) == 'no' );
511
			}
512
			else {
513
				$custom_css_post_id = Jetpack_Custom_CSS::post_id();
514
515
				if ( $custom_css_post_id ) {
516
					$custom_css_add = get_post_meta( $custom_css_post_id, 'custom_css_add', true );
517
518
					// It is possible for the CSS to be stored in a post but for the safecss_add option
519
					// to have not been upgraded yet if the user hasn't opened their Custom CSS editor
520
					// since October 2012.
521
					if ( ! empty( $custom_css_add ) )
522
						return (bool) ( $custom_css_add === 'no' );
523
				}
524
525
				return (bool) ( Jetpack_Options::get_option_and_ensure_autoload( 'safecss_add', '' ) == 'no' );
526
			}
527
		}
528
	}
529
530
	static function is_preview() {
531
		return isset( $_GET['csspreview'] ) && $_GET['csspreview'] === 'true';
532
	}
533
534
	/**
535
	 * Currently this filter function gets called on
536
	 * 'template_redirect' action and
537
	 * 'admin_init' action
538
	 */
539 View Code Duplication
	static function set_content_width(){
540
		// Don't apply this filter on the Edit CSS page
541
		if ( isset( $_GET ) && isset( $_GET['page'] ) &&  'editcss' == $_GET['page'] && is_admin() ) {
542
			return;
543
		}
544
545
		$GLOBALS['content_width'] = Jetpack::get_content_width();
546
	}
547
548
	/*
549
	 * False when the site has the Custom Design upgrade.
550
	 * Used only on WordPress.com.
551
	 */
552
	static function is_freetrial() {
553
		/**
554
		 * Determine if a WordPress.com site uses a Free trial of the Custom Design Upgrade.
555
		 * Used only on WordPress.com.
556
		 *
557
		 * @module custom-css
558
		 *
559
		 * @since 1.7.0
560
		 *
561
		 * @param bool false Does the site use a Free trial of the Custom Design Upgrade. Default to false.
562
		 */
563
		return apply_filters( 'safecss_is_freetrial', false );
564
	}
565
566
	static function get_preprocessor_key() {
567
		$safecss_post = Jetpack_Custom_CSS::get_current_revision();
568
		return get_post_meta( $safecss_post['ID'], 'custom_css_preprocessor', true );
569
	}
570
571
	static function get_preprocessor() {
572
		/** This filter is documented in modules/custom-css/custom-css.php */
573
		$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
574
		$selected_preprocessor_key = self::get_preprocessor_key();
575
		$selected_preprocessor = isset( $preprocessors[ $selected_preprocessor_key ] ) ? $preprocessors[ $selected_preprocessor_key ] : null;
576
		return $selected_preprocessor;
577
	}
578
579
	static function get_css( $compressed = false ) {
580
		/**
581
		 * Filter the Custom CSS returned.
582
		 * Can be used to return an error, or no CSS at all.
583
		 *
584
		 * @module custom-css
585
		 *
586
		 * @since 1.7.0
587
		 *
588
		 * @param bool false Should we return an error instead of the Custom CSS. Default to false.
589
		 */
590
		$default_css = apply_filters( 'safecss_get_css_error', false );
591
592
		if ( $default_css !== false )
593
			return $default_css;
594
595
		$option = ( Jetpack_Custom_CSS::is_preview() || Jetpack_Custom_CSS::is_freetrial() ) ? 'safecss_preview' : 'safecss';
596
		$css = '';
597
598
		if ( 'safecss' == $option ) {
599
			// Don't bother checking for a migrated 'safecss' option if it never existed.
600
			if ( false === get_option( 'safecss' ) || get_option( 'safecss_revision_migrated' ) ) {
601
				$safecss_post = Jetpack_Custom_CSS::get_post();
602
				if ( ! empty( $safecss_post ) ) {
603
					$css = ( $compressed && $safecss_post['post_content_filtered'] ) ? $safecss_post['post_content_filtered'] : $safecss_post['post_content'];
604
				}
605
			} else {
606
				$current_revision = Jetpack_Custom_CSS::get_current_revision();
607
				if ( false === $current_revision ) {
608
					$css = '';
609
				} else {
610
					$css = ( $compressed && $current_revision['post_content_filtered'] ) ? $current_revision['post_content_filtered'] : $current_revision['post_content'];
611
				}
612
			}
613
614
			// Fix for un-migrated Custom CSS
615
			if ( empty( $safecss_post ) ) {
616
				$_css = get_option( 'safecss' );
617
				if ( !empty( $_css ) ) {
618
					$css = $_css;
619
				}
620
			}
621
		}
622
		else if ( 'safecss_preview' == $option ) {
623
			$safecss_post = Jetpack_Custom_CSS::get_current_revision();
624
			$css = $safecss_post['post_content'];
625
			$css = Jetpack_Custom_CSS::minify( $css, get_post_meta( $safecss_post['ID'], 'custom_css_preprocessor', true ) );
626
		}
627
628
		$css = str_replace( array( '\\\00BB \\\0020', '\0BB \020', '0BB 020' ), '\00BB \0020', $css );
629
630
		if ( empty( $css ) ) {
631
			$css = "/*\n"
632
				. wordwrap(
633
					/**
634
					 * Filter the default message displayed in the Custom CSS editor.
635
					 *
636
					 * @module custom-css
637
					 *
638
					 * @since 1.7.0
639
					 *
640
					 * @param string $str Default Custom CSS editor content.
641
					 */
642
					apply_filters(
643
						'safecss_default_css',
644
						__(
645
							"Welcome to Custom CSS!\n\nTo learn how this works, see http://wp.me/PEmnE-Bt",
646
							'jetpack'
647
						)
648
					)
649
				)
650
				. "\n*/";
651
		}
652
653
		/**
654
		 * Filter the Custom CSS returned from the editor.
655
		 *
656
		 * @module custom-css
657
		 *
658
		 * @since 1.7.0
659
		 *
660
		 * @param string $css Custom CSS.
661
		 */
662
		$css = apply_filters( 'safecss_css', $css );
663
664
		return $css;
665
	}
666
667
	static function replace_insecure_urls( $css ) {
668
		if ( ! function_exists( '_sa_get_frontend_https_url_replacement_map' ) ) {
669
			return $css;
670
		}
671
		list( $http_urls, $secure_urls ) = _sa_get_frontend_https_url_replacement_map();
672
673
		return str_replace( $http_urls, $secure_urls, $css );
674
	}
675
676
	static function print_css() {
677
678
		/**
679
		 * Fires right before printing the custom CSS inside the <head> element.
680
		 *
681
		 * @module custom-css
682
		 *
683
		 * @since 1.7.0
684
		 */
685
		do_action( 'safecss_print_pre' );
686
		$css = Jetpack_Custom_CSS::get_css( true );
687
		echo self::replace_insecure_urls( $css );
688
	}
689
690
	static function should_we_inline_custom_css( $should_we, $css ) {
691
		// If the CSS is less than 2,000 characters, inline it! otherwise return what was passed in.
692
		return ( strlen( $css ) < 2000 ) ? true : $should_we;
693
	}
694
695
	static function link_tag() {
696
		global $blog_id, $current_blog;
697
698
		if (
699
			/**
700
			 * Do not include any CSS on the page if the CSS includes an error.
701
			 * Setting this filter to true stops any Custom CSS from being enqueued.
702
			 *
703
			 * @module custom-css
704
			 *
705
			 * @since 1.7.0
706
			 *
707
			 * @param bool false Does the CSS include an error. Default to false.
708
			 */
709
			apply_filters( 'safecss_style_error', false )
710
		) {
711
			return;
712
		}
713
714
		if ( ! is_super_admin() && isset( $current_blog ) && ( 1 == $current_blog->spam || 1 == $current_blog->deleted ) )
715
			return;
716
717
		if ( Jetpack_Custom_CSS::is_customizer_preview() )
718
			return;
719
720
		$css    = '';
721
		$option = Jetpack_Custom_CSS::is_preview() ? 'safecss_preview' : 'safecss';
722
723
		if ( 'safecss' == $option ) {
724
			if ( Jetpack_Options::get_option_and_ensure_autoload( 'safecss_revision_migrated', '0' ) ) {
725
				$safecss_post = Jetpack_Custom_CSS::get_post();
726
727
				if ( ! empty( $safecss_post['post_content'] ) ) {
728
					$css = $safecss_post['post_content'];
729
				}
730 View Code Duplication
			} else {
731
				$current_revision = Jetpack_Custom_CSS::get_current_revision();
732
733
				if ( ! empty( $current_revision['post_content'] ) ) {
734
					$css = $current_revision['post_content'];
735
				}
736
			}
737
738
			// Fix for un-migrated Custom CSS
739
			if ( empty( $safecss_post ) ) {
740
				$_css = Jetpack_Options::get_option_and_ensure_autoload( 'safecss', '' );
741
				if ( !empty( $_css ) ) {
742
					$css = $_css;
743
				}
744
			}
745
		}
746
747 View Code Duplication
		if ( 'safecss_preview' == $option ) {
748
			$safecss_post = Jetpack_Custom_CSS::get_current_revision();
749
750
			if ( !empty( $safecss_post['post_content'] ) ) {
751
				$css = $safecss_post['post_content'];
752
			}
753
		}
754
755
		$css = str_replace( array( '\\\00BB \\\0020', '\0BB \020', '0BB 020' ), '\00BB \0020', $css );
756
757
		if ( $css == '' )
758
			return;
759
760
		if (
761
			/**
762
			 * Allow inserting CSS inline instead of through a separate file.
763
			 *
764
			 * @module custom-css
765
			 *
766
			 * @since 3.4.0
767
			 *
768
			 * @param bool false Should the CSS be added inline instead of through a separate file. Default to false.
769
			 * @param string $css Custom CSS.
770
			 */
771
			apply_filters( 'safecss_embed_style', false, $css )
772
		) {
773
774
			echo "\r\n" . '<style id="custom-css-css">' . Jetpack_Custom_CSS::get_css( true ) . "</style>\r\n";
775
776
		} else {
777
778
			$href = home_url( '/' );
779
			$href = add_query_arg( 'custom-css', 1, $href );
780
			$href = add_query_arg( 'csblog', $blog_id, $href );
781
			$href = add_query_arg( 'cscache', 6, $href );
782
			$href = add_query_arg( 'csrev', (int) get_option( $option . '_rev' ), $href );
783
784
			/**
785
			 * Filter the Custom CSS link enqueued in the head.
786
			 *
787
			 * @module custom-css
788
			 *
789
			 * @since 1.7.0
790
			 *
791
			 * @param string $href Custom CSS link enqueued in the head.
792
			 * @param string $blog_id Blog ID.
793
			 */
794
			$href = apply_filters( 'safecss_href', $href, $blog_id );
795
796
			if ( Jetpack_Custom_CSS::is_preview() )
797
				$href = add_query_arg( 'csspreview', 'true', $href );
798
799
			?>
800
			<link rel="stylesheet" id="custom-css-css" type="text/css" href="<?php echo esc_url( $href ); ?>" />
801
			<?php
802
803
		}
804
805
		/**
806
		 * Fires after creating the <link> in the <head> element for the custom css stylesheet.
807
		 *
808
		 * @module custom-css
809
		 *
810
		 * @since 2.2.2
811
		 */
812
		do_action( 'safecss_link_tag_post' );
813
	}
814
815
	static function style_filter( $current ) {
816
		if ( Jetpack_Custom_CSS::is_freetrial() && ( ! Jetpack_Custom_CSS::is_preview() || ! current_user_can( 'switch_themes' ) ) )
817
			return $current;
818
		else if ( Jetpack_Custom_CSS::skip_stylesheet() )
819
			/**
820
			 * Filter the default blank Custom CSS URL.
821
			 *
822
			 * @module custom-css
823
			 *
824
			 * @since 2.2.1
825
			 *
826
			 * @param string $url Default blank Custom CSS URL.
827
			 */
828
			return apply_filters( 'safecss_style_filter_url', plugins_url( 'custom-css/css/blank.css', __FILE__ ) );
829
830
		return $current;
831
	}
832
833
	static function buffer( $html ) {
834
		$html = str_replace( '</body>', Jetpack_Custom_CSS::preview_flag(), $html );
835
		return preg_replace_callback( '!href=([\'"])(.*?)\\1!', array( 'Jetpack_Custom_CSS', 'preview_links' ), $html );
836
	}
837
838
	static function preview_links( $matches ) {
839
		if ( 0 !== strpos( $matches[2], get_option( 'home' ) ) )
840
			return $matches[0];
841
842
		$link = wp_specialchars_decode( $matches[2] );
843
		$link = add_query_arg( 'csspreview', 'true', $link );
844
		$link = esc_url( $link );
845
		return "href={$matches[1]}$link{$matches[1]}";
846
	}
847
848
	/**
849
	 * Places a black bar above every preview page
850
	 */
851
	static function preview_flag() {
852
		if ( is_admin() )
853
			return;
854
855
		$message = esc_html__( 'Preview: changes must be saved or they will be lost', 'jetpack' );
856
		/**
857
		 * Filter the Preview message displayed on the site when previewing custom CSS, before to save it.
858
		 *
859
		 * @module custom-css
860
		 *
861
		 * @since 1.7.0
862
		 *
863
		 * @param string $message Custom CSS preview message.
864
		 */
865
		$message = apply_filters( 'safecss_preview_message', $message );
866
867
		$preview_flag_js = "var flag = document.createElement('div');
868
		flag.innerHTML = " . json_encode( $message ) . ";
869
		flag.style.background = '#FF6600';
870
		flag.style.color = 'white';
871
		flag.style.textAlign = 'center';
872
		flag.style.fontSize = '15px';
873
		flag.style.padding = '2px';
874
		flag.style.fontFamily = 'sans-serif';
875
		document.body.style.paddingTop = '0px';
876
		document.body.insertBefore(flag, document.body.childNodes[0]);
877
		";
878
879
		/**
880
		 * Filter the Custom CSS preview message JS styling.
881
		 *
882
		 * @module custom-css
883
		 *
884
		 * @since 1.7.0
885
		 *
886
		 * @param string $preview_flag_js Custom CSS preview message JS styling.
887
		 */
888
		$preview_flag_js = apply_filters( 'safecss_preview_flag_js', $preview_flag_js );
889
		if ( $preview_flag_js ) {
890
			$preview_flag_js = '<script type="text/javascript">
891
	// <![CDATA[
892
	' . $preview_flag_js . '
893
	// ]]>
894
	</script>';
895
		}
896
897
		return $preview_flag_js;
898
	}
899
900
	static function menu() {
901
		$parent = 'themes.php';
0 ignored issues
show
Unused Code introduced by
$parent 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...
902
		$title = __( 'Edit CSS', 'jetpack' );
903
		$hook = add_theme_page( $title, $title, 'edit_theme_options', 'editcss', array( 'Jetpack_Custom_CSS', 'admin' ) );
904
905
		add_action( "load-revision.php", array( 'Jetpack_Custom_CSS', 'prettify_post_revisions' ) );
906
		add_action( "load-$hook", array( 'Jetpack_Custom_CSS', 'update_title' ) );
907
	}
908
909
	/**
910
	 * Adds a menu item in the appearance section for this plugin's administration
911
	 * page. Also adds hooks to enqueue the CSS and JS for the admin page.
912
	 */
913
	static function update_title() {
914
		global $title;
915
		$title = __( 'CSS', 'jetpack' );
916
	}
917
918
	static function prettify_post_revisions() {
919
		add_filter( 'the_title', array( 'Jetpack_Custom_CSS', 'post_title' ), 10, 2 );
920
	}
921
922
	static function post_title( $title, $post_id ) {
923
		if ( !$post_id = (int) $post_id ) {
924
			return $title;
925
		}
926
927
		if ( !$post = get_post( $post_id ) ) {
928
			return $title;
929
		}
930
931
		if ( 'safecss' != $post->post_type ) {
932
			return $title;
933
		}
934
935
		return __( 'Custom CSS Stylesheet', 'jetpack' );
936
	}
937
938
	static function enqueue_scripts( $hook ) {
939
		if ( 'appearance_page_editcss' != $hook )
940
			return;
941
942
		wp_enqueue_script( 'postbox' );
943
		wp_enqueue_script( 'custom-css-editor', plugins_url( 'custom-css/js/css-editor.js', __FILE__ ), 'jquery', '20130325', true );
944
		wp_enqueue_style( 'custom-css-editor', plugins_url( 'custom-css/css/css-editor.css', __FILE__ ) );
945
946
		if ( defined( 'SAFECSS_USE_ACE' ) && SAFECSS_USE_ACE ) {
947
			wp_register_style( 'jetpack-css-codemirror', plugins_url( 'custom-css/css/codemirror.css', __FILE__ ), array(), '20120905' );
948
			wp_enqueue_style( 'jetpack-css-use-codemirror', plugins_url( 'custom-css/css/use-codemirror.css', __FILE__ ), array( 'jetpack-css-codemirror' ), '20120905' );
949
950
			wp_register_script( 'jetpack-css-codemirror', plugins_url( 'custom-css/js/codemirror.min.js', __FILE__ ), array(), '3.16', true );
951
			wp_enqueue_script( 'jetpack-css-use-codemirror', plugins_url( 'custom-css/js/use-codemirror.js', __FILE__ ), array( 'jquery', 'underscore', 'jetpack-css-codemirror' ), '20131009', true );
952
		}
953
	}
954
955
	static function saved_message() {
956
		echo '<div id="message" class="updated fade"><p><strong>' . __( 'Stylesheet saved.', 'jetpack' ) . '</strong></p></div>';
957
	}
958
959
	static function admin() {
960
		add_meta_box( 'submitdiv', __( 'Publish', 'jetpack' ), array( __CLASS__, 'publish_box' ), 'editcss', 'side' );
961
		add_action( 'custom_css_submitbox_misc_actions', array( __CLASS__, 'content_width_settings' ) );
962
963
		$safecss_post = Jetpack_Custom_CSS::get_post();
964
965
		if ( ! empty( $safecss_post ) && 0 < $safecss_post['ID'] && wp_get_post_revisions( $safecss_post['ID'], array( 'posts_per_page' => 1 ) ) )
966
			add_meta_box( 'revisionsdiv', __( 'CSS Revisions', 'jetpack' ), array( __CLASS__, 'revisions_meta_box' ), 'editcss', 'side' );
967
		?>
968
		<div class="wrap">
969
			<?php
970
971
			/**
972
			 * Fires right before the custom css page begins.
973
			 *
974
			 * @module custom-css
975
			 *
976
			 * @since 1.7.0
977
			 */
978
			do_action( 'custom_design_header' );
979
980
			?>
981
			<h1><?php _e( 'CSS Stylesheet Editor', 'jetpack' ); ?></h1>
982
			<form id="safecssform" action="" method="post">
983
				<?php wp_nonce_field( 'safecss' ) ?>
984
				<?php wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); ?>
985
				<?php wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?>
986
				<input type="hidden" name="action" value="save" />
987
				<div id="poststuff">
988
					<p class="css-support">
989
					<?php
990
						/**
991
						 * Filter the intro text appearing above the Custom CSS Editor.
992
						 *
993
						 * @module custom-css
994
						 *
995
						 * @since 1.7.0
996
						 *
997
						 * @param string $str Intro text appearing above the Custom CSS editor.
998
						 */
999
						echo apply_filters( 'safecss_intro_text', __( 'New to CSS? Start with a <a href="http://www.htmldog.com/guides/cssbeginner/" target="_blank">beginner tutorial</a>. Questions?
1000
		Ask in the <a href="https://wordpress.org/support/forum/themes-and-templates" target="_blank">Themes and Templates forum</a>.', 'jetpack' ) );
1001
					?></p>
1002
					<p class="css-support"><?php echo __( 'Note: Custom CSS will be reset when changing themes.', 'jetpack' ); ?></p>
1003
1004
					<div id="post-body" class="metabox-holder columns-2">
1005
						<div id="post-body-content">
1006
							<div class="postarea">
1007
								<textarea id="safecss" name="safecss"<?php if ( SAFECSS_USE_ACE ) echo ' class="hide-if-js"'; ?>><?php echo esc_textarea( Jetpack_Custom_CSS::get_css() ); ?></textarea>
1008
								<div class="clear"></div>
1009
							</div>
1010
						</div>
1011
						<div id="postbox-container-1" class="postbox-container">
1012
						<?php do_meta_boxes( 'editcss', 'side', $safecss_post ); ?>
1013
					</div>
1014
					</div>
1015
					<br class="clear" />
1016
				</div>
1017
			</form>
1018
		</div>
1019
		<?php
1020
	}
1021
1022
	/**
1023
	 * Content width setting callback
1024
	 */
1025
	static function content_width_settings() {
1026
		$safecss_post = Jetpack_Custom_CSS::get_current_revision();
1027
1028
		$custom_content_width = get_post_meta( $safecss_post['ID'], 'content_width', true );
1029
1030
		// If custom content width hasn't been overridden and the theme has a content_width value, use that as a default.
1031
		if ( $custom_content_width <= 0 && ! empty( $GLOBALS['content_width'] ) )
1032
			$custom_content_width = $GLOBALS['content_width'];
1033
1034
		if ( ! $custom_content_width || ( isset( $GLOBALS['content_width'] ) && $custom_content_width == $GLOBALS['content_width'] ) )
1035
			$custom_content_width = '';
1036
1037
		?>
1038
		<div class="misc-pub-section">
1039
			<label><?php esc_html_e( 'Media Width:', 'jetpack' ); ?></label>
1040
			<span id="content-width-display" data-default-text="<?php esc_attr_e( 'Default', 'jetpack' ); ?>" data-custom-text="<?php esc_attr_e( '%s px', 'jetpack' ); ?>"><?php echo $custom_content_width ? sprintf( esc_html__( '%s px', 'jetpack' ), $custom_content_width ) : esc_html_e( 'Default', 'jetpack' ); ?></span>
1041
			<a class="edit-content-width hide-if-no-js" href="#content-width"><?php echo esc_html_e( 'Edit', 'jetpack' ); ?></a>
1042
			<div id="content-width-select" class="hide-if-js">
1043
				<input type="hidden" name="custom_content_width" id="custom_content_width" value="<?php echo esc_attr( $custom_content_width ); ?>" />
1044
				<p>
1045
					<?php
1046
1047
					printf(
1048
						__( 'Limit width to %1$s pixels for full size images. (<a href="%2$s" target="_blank">More info</a>.)', 'jetpack' ),
1049
						'<input type="text" id="custom_content_width_visible" value="' . esc_attr( $custom_content_width ) . '" size="4" />',
1050
						/**
1051
						 * Filter the Custom CSS limited width's support doc URL.
1052
						 *
1053
						 * @module custom-css
1054
						 *
1055
						 * @since 2.2.3
1056
						 *
1057
						 * @param string $url Custom CSS limited width's support doc URL.
1058
						 */
1059
						apply_filters( 'safecss_limit_width_link', 'http://jetpack.com/support/custom-css/#limited-width' )
1060
					);
1061
1062
					?>
1063
				</p>
1064
				<?php
1065
1066
				if ( !empty( $GLOBALS['content_width'] ) && $custom_content_width != $GLOBALS['content_width'] ) {
1067
					if ( function_exists( 'wp_get_theme' ) )
1068
						$current_theme = wp_get_theme()->Name;
1069
					else
1070
						$current_theme = get_current_theme();
1071
1072
					?>
1073
					<p><?php printf( __( 'The default content width for the %s theme is %d pixels.', 'jetpack' ), $current_theme, intval( $GLOBALS['content_width'] ) ); ?></p>
1074
					<?php
1075
				}
1076
1077
				?>
1078
				<a class="save-content-width hide-if-no-js button" href="#content-width"><?php esc_html_e( 'OK', 'jetpack' ); ?></a>
1079
				<a class="cancel-content-width hide-if-no-js" href="#content-width"><?php esc_html_e( 'Cancel', 'jetpack' ); ?></a>
1080
			</div>
1081
			<script type="text/javascript">
1082
				jQuery( function ( $ ) {
1083
					var defaultContentWidth = <?php echo isset( $GLOBALS['content_width'] ) ? json_encode( intval( $GLOBALS['content_width'] ) ) : 0; ?>;
1084
1085
					$( '.edit-content-width' ).bind( 'click', function ( e ) {
1086
						e.preventDefault();
1087
1088
						$( '#content-width-select' ).slideDown();
1089
						$( this ).hide();
1090
					} );
1091
1092
					$( '.cancel-content-width' ).bind( 'click', function ( e ) {
1093
						e.preventDefault();
1094
1095
						$( '#content-width-select' ).slideUp( function () {
1096
							$( '.edit-content-width' ).show();
1097
							$( '#custom_content_width_visible' ).val( $( '#custom_content_width' ).val() );
1098
						} );
1099
					} );
1100
1101
					$( '.save-content-width' ).bind( 'click', function ( e ) {
1102
						e.preventDefault();
1103
1104
						$( '#content-width-select' ).slideUp();
1105
1106
						var newContentWidth = parseInt( $( '#custom_content_width_visible' ).val(), 10 );
1107
1108
						if ( newContentWidth && newContentWidth != defaultContentWidth ) {
1109
							$( '#content-width-display' ).text(
1110
								$( '#content-width-display' )
1111
									.data( 'custom-text' )
1112
										.replace( '%s', $( '#custom_content_width_visible' ).val() )
1113
							);
1114
						}
1115
						else {
1116
							$( '#content-width-display' ).text( $( '#content-width-display' ).data( 'default-text' ) );
1117
						}
1118
1119
						$( '#custom_content_width' ).val( $( '#custom_content_width_visible' ).val() );
1120
						$( '.edit-content-width' ).show();
1121
					} );
1122
				} );
1123
			</script>
1124
		</div>
1125
		<?php
1126
	}
1127
1128
	static function publish_box() {
1129
		?>
1130
		<div id="minor-publishing">
1131
			<div id="misc-publishing-actions">
1132
				<?php
1133
1134
				/**
1135
				 * Filter the array of available Custom CSS preprocessors.
1136
				 *
1137
				 * @module custom-css
1138
				 *
1139
				 * @since 2.0.3
1140
				 *
1141
				 * @param array array() Empty by default.
1142
				 */
1143
				$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
1144
1145
				if ( ! empty( $preprocessors ) ) {
1146
					$safecss_post = Jetpack_Custom_CSS::get_current_revision();
1147
					$selected_preprocessor_key = get_post_meta( $safecss_post['ID'], 'custom_css_preprocessor', true );
1148
					$selected_preprocessor = isset( $preprocessors[$selected_preprocessor_key] ) ? $preprocessors[$selected_preprocessor_key] : null;
1149
1150
					?>
1151
					<div class="misc-pub-section">
1152
						<label><?php esc_html_e( 'Preprocessor:', 'jetpack' ); ?></label>
1153
						<span id="preprocessor-display"><?php echo esc_html( $selected_preprocessor ? $selected_preprocessor['name'] : __( 'None', 'jetpack' ) ); ?></span>
1154
						<a class="edit-preprocessor hide-if-no-js" href="#preprocessor"><?php echo esc_html_e( 'Edit', 'jetpack' ); ?></a>
1155
						<div id="preprocessor-select" class="hide-if-js">
1156
							<input type="hidden" name="custom_css_preprocessor" id="custom_css_preprocessor" value="<?php echo esc_attr( $selected_preprocessor_key ); ?>" />
1157
							<select id="preprocessor_choices">
1158
								<option value=""><?php esc_html_e( 'None', 'jetpack' ); ?></option>
1159
								<?php
1160
1161
								foreach ( $preprocessors as $preprocessor_key => $preprocessor ) {
1162
								?>
1163
									<option value="<?php echo esc_attr( $preprocessor_key ); ?>" <?php selected( $selected_preprocessor_key, $preprocessor_key ); ?>><?php echo esc_html( $preprocessor['name'] ); ?></option>
1164
									<?php
1165
								}
1166
1167
								?>
1168
							</select>
1169
							<a class="save-preprocessor hide-if-no-js button" href="#preprocessor"><?php esc_html_e( 'OK', 'jetpack' ); ?></a>
1170
							<a class="cancel-preprocessor hide-if-no-js" href="#preprocessor"><?php esc_html_e( 'Cancel', 'jetpack' ); ?></a>
1171
						</div>
1172
					</div>
1173
					<?php
1174
				}
1175
1176
				$safecss_post = Jetpack_Custom_CSS::get_current_revision();
1177
1178
				$add_css = ( get_post_meta( $safecss_post['ID'], 'custom_css_add', true ) != 'no' );
1179
1180
				?>
1181
				<div class="misc-pub-section">
1182
					<label><?php esc_html_e( 'Mode:', 'jetpack' ); ?></label>
1183
					<span id="css-mode-display"><?php echo esc_html( $add_css ? __( 'Add-on', 'jetpack' ) : __( 'Replacement', 'jetpack' ) ); ?></span>
1184
					<a class="edit-css-mode hide-if-no-js" href="#css-mode"><?php echo esc_html_e( 'Edit', 'jetpack' ); ?></a>
1185
					<div id="css-mode-select" class="hide-if-js">
1186
						<input type="hidden" name="add_to_existing" id="add_to_existing" value="<?php echo $add_css ? 'true' : 'false'; ?>" />
1187
						<p>
1188
							<label>
1189
								<input type="radio" name="add_to_existing_display" value="true" <?php checked( $add_css ); ?>/>
1190
								<?php _e( 'Add-on CSS <b>(Recommended)</b>', 'jetpack' ); ?>
1191
							</label>
1192
							<br />
1193
							<label>
1194
								<input type="radio" name="add_to_existing_display" value="false" <?php checked( ! $add_css ); ?>/>
1195
								<?php printf(
1196
									__( 'Replace <a href="%s">theme\'s CSS</a> <b>(Advanced)</b>', 'jetpack' ),
1197
									/**
1198
									 * Filter the theme's stylesheet URL.
1199
									 *
1200
									 * @module custom-css
1201
									 *
1202
									 * @since 1.7.0
1203
									 *
1204
									 * @param string $url Active theme's stylesheet URL. Default to get_stylesheet_uri().
1205
									 */
1206
									apply_filters( 'safecss_theme_stylesheet_url', get_stylesheet_uri() )
1207
								); ?>
1208
							</label>
1209
						</p>
1210
						<a class="save-css-mode hide-if-no-js button" href="#css-mode"><?php esc_html_e( 'OK', 'jetpack' ); ?></a>
1211
						<a class="cancel-css-mode hide-if-no-js" href="#css-mode"><?php esc_html_e( 'Cancel', 'jetpack' ); ?></a>
1212
					</div>
1213
				</div>
1214
				<?php
1215
1216
				/**
1217
				 * Allows addition of elements to the submit box for custom css on the wp-admin side.
1218
				 *
1219
				 * @module custom-css
1220
				 *
1221
				 * @since 2.0.3
1222
				 */
1223
				do_action( 'custom_css_submitbox_misc_actions' );
1224
1225
				?>
1226
			</div>
1227
		</div>
1228
		<div id="major-publishing-actions">
1229
			<input type="button" class="button" id="preview" name="preview" value="<?php esc_attr_e( 'Preview', 'jetpack' ) ?>" />
1230
			<div id="publishing-action">
1231
				<input type="submit" class="button-primary" id="save" name="save" value="<?php ( Jetpack_Custom_CSS::is_freetrial() ) ? esc_attr_e( 'Save &amp; Buy Upgrade', 'jetpack' ) : esc_attr_e( 'Save Stylesheet', 'jetpack' ); ?>" />
1232
			</div>
1233
		</div>
1234
		<?php
1235
	}
1236
1237
	/**
1238
	 * Render metabox listing CSS revisions and the themes that correspond to the revisions.
1239
	 * Called by safecss_admin
1240
	 *
1241
	 * @global $post
1242
	 * @param array $safecss_post
1243
	 * @uses wp_revisions_to_keep
1244
	 * @uses WP_Query
1245
	 * @uses wp_post_revision_title
1246
	 * @uses esc_html
1247
	 * @uses add_query_arg
1248
	 * @uses menu_page_url
1249
	 * @uses wp_reset_query
1250
	 * @return string
1251
	 */
1252
	static function revisions_meta_box( $safecss_post ) {
1253
1254
		$show_all_revisions = isset( $_GET['show_all_rev'] );
1255
1256
		if ( function_exists( 'wp_revisions_to_keep' ) ) {
1257
			$max_revisions = wp_revisions_to_keep( (object) $safecss_post );
1258
		} else {
1259
			$max_revisions = defined( 'WP_POST_REVISIONS' ) && is_numeric( WP_POST_REVISIONS ) ? (int) WP_POST_REVISIONS : 25;
1260
		}
1261
1262
		$posts_per_page = $show_all_revisions ? $max_revisions : 6;
1263
1264
		$revisions = new WP_Query( array(
1265
			'posts_per_page' => $posts_per_page,
1266
			'post_type' => 'revision',
1267
			'post_status' => 'inherit',
1268
			'post_parent' => $safecss_post['ID'],
1269
			'orderby' => 'date',
1270
			'order' => 'DESC'
1271
		) );
1272
1273
		if ( $revisions->have_posts() ) { ?>
1274
			<ul class="post-revisions"><?php
1275
1276
			global $post;
1277
1278
			while ( $revisions->have_posts() ) :
1279
				$revisions->the_post();
1280
1281
				?><li>
1282
					<?php
1283
						echo wp_post_revision_title( $post );
1284
1285
						if ( ! empty( $post->post_excerpt ) )
1286
							echo ' (' . esc_html( $post->post_excerpt ) . ')';
1287
					?>
1288
				</li><?php
1289
1290
			endwhile;
1291
1292
			?></ul><?php
1293
1294
			if ( $revisions->found_posts > 6 && !$show_all_revisions ) {
1295
				?>
1296
				<br>
1297
				<a href="<?php echo add_query_arg( 'show_all_rev', 'true', menu_page_url( 'editcss', false ) ); ?>"><?php esc_html_e( 'Show all', 'jetpack' ); ?></a>
1298
				<?php
1299
			}
1300
		}
1301
1302
		wp_reset_query();
1303
	}
1304
1305
	/**
1306
	 * Hook in init at priority 11 to disable custom CSS.
1307
	 */
1308
	static function disable() {
1309
		remove_action( 'wp_head', array( 'Jetpack_Custom_CSS', 'link_tag' ), 101 );
1310
	    remove_filter( 'stylesheet_uri', array( 'Jetpack_Custom_CSS', 'style_filter' ) );
1311
	}
1312
1313
	/**
1314
	 * Reset all aspects of Custom CSS on a theme switch so that changing
1315
	 * themes is a sure-fire way to get a clean start.
1316
	 */
1317
	static function reset() {
1318
		$safecss_post_id = Jetpack_Custom_CSS::save_revision( '' );
1319
		$safecss_revision = Jetpack_Custom_CSS::get_current_revision();
1320
1321
		update_option( 'safecss_rev', intval( get_option( 'safecss_rev' ) ) + 1 );
1322
1323
		update_post_meta( $safecss_post_id, 'custom_css_add', 'yes' );
1324
		update_post_meta( $safecss_post_id, 'content_width', false );
1325
		update_post_meta( $safecss_post_id, 'custom_css_preprocessor', '' );
1326
1327
		delete_option( 'safecss_add' );
1328
		delete_option( 'safecss_content_width' );
1329
1330
		update_metadata( 'post', $safecss_revision['ID'], 'custom_css_add', 'yes' );
1331
		update_metadata( 'post', $safecss_revision['ID'], 'content_width', false );
1332
		update_metadata( 'post', $safecss_revision['ID'], 'custom_css_preprocessor', '' );
1333
1334
		delete_option( 'safecss_preview_add' );
1335
	}
1336
1337
	static function is_customizer_preview() {
1338
		if ( isset ( $GLOBALS['wp_customize'] ) )
1339
			return ! $GLOBALS['wp_customize']->is_theme_active();
1340
1341
		return false;
1342
	}
1343
1344
	static function minify( $css, $preprocessor = '' ) {
1345
		if ( ! $css )
1346
			return '';
1347
1348 View Code Duplication
		if ( $preprocessor ) {
1349
			/** This filter is documented in modules/custom-css/custom-css.php */
1350
			$preprocessors = apply_filters( 'jetpack_custom_css_preprocessors', array() );
1351
1352
			if ( isset( $preprocessors[$preprocessor] ) ) {
1353
				$css = call_user_func( $preprocessors[$preprocessor]['callback'], $css );
1354
			}
1355
		}
1356
1357
		safecss_class();
1358
		$csstidy = new csstidy();
1359
		$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...
1360
1361
		$csstidy->set_cfg( 'remove_bslash',              false );
1362
		$csstidy->set_cfg( 'compress_colors',            true );
1363
		$csstidy->set_cfg( 'compress_font-weight',       true );
1364
		$csstidy->set_cfg( 'remove_last_;',              true );
1365
		$csstidy->set_cfg( 'case_properties',            true );
1366
		$csstidy->set_cfg( 'discard_invalid_properties', true );
1367
		$csstidy->set_cfg( 'css_level',                  'CSS3.0' );
1368
		$csstidy->set_cfg( 'template', 'highest');
1369
		$csstidy->parse( $css );
1370
1371
		return $csstidy->print->plain();
1372
	}
1373
1374
	/**
1375
	 * When restoring a SafeCSS post revision, also copy over the
1376
	 * content_width and custom_css_add post metadata.
1377
	 */
1378
	static function restore_revision( $_post_id, $_revision_id ) {
1379
		$_post = get_post( $_post_id );
1380
1381
		if ( 'safecss' != $_post->post_type )
1382
			return;
1383
1384
		$safecss_revision = Jetpack_Custom_CSS::get_current_revision();
1385
1386
		$content_width = get_post_meta( $_revision_id, 'content_width', true );
1387
		$custom_css_add = get_post_meta( $_revision_id, 'custom_css_add', true );
1388
		$preprocessor = get_post_meta( $_revision_id, 'custom_css_preprocessor', true );
1389
1390
		update_metadata( 'post', $safecss_revision['ID'], 'content_width', $content_width );
1391
		update_metadata( 'post', $safecss_revision['ID'], 'custom_css_add', $custom_css_add );
1392
		update_metadata( 'post', $safecss_revision['ID'], 'custom_css_preprocessor', $preprocessor );
1393
1394
		delete_option( 'safecss_add' );
1395
		delete_option( 'safecss_content_width' );
1396
1397
		update_post_meta( $_post->ID, 'content_width', $content_width );
1398
		update_post_meta( $_post->ID, 'custom_css_add', $custom_css_add );
1399
		update_post_meta( $_post->ID, 'custom_css_preprocessor', $preprocessor );
1400
1401
		delete_option( 'safecss_preview_add' );
1402
	}
1403
1404
	/**
1405
	 * Migration routine for moving safecss from wp_options to wp_posts to support revisions
1406
	 *
1407
	 * @return void
1408
	 */
1409
	static function upgrade() {
1410
		$css = get_option( 'safecss' );
1411
1412
		if ( get_option( 'safecss_revision_migrated' ) ) {
1413
			return false;
1414
		}
1415
1416
		// Check if CSS is stored in wp_options
1417
		if ( $css ) {
1418
			// Remove the async actions from publish_post
1419
			remove_action( 'publish_post', 'queue_publish_post' );
1420
1421
			$post = array();
1422
			$post['post_content'] = $css;
1423
			$post['post_title'] = 'safecss';
1424
			$post['post_status'] = 'publish';
1425
			$post['post_type'] = 'safecss';
1426
1427
			// Insert the CSS into wp_posts
1428
			$post_id = wp_insert_post( $post );
1429
			// Check for errors
1430
			if ( !$post_id or is_wp_error( $post_id ) )
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
1431
				die( $post_id->get_error_message() );
0 ignored issues
show
Coding Style Compatibility introduced by
The method upgrade() 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...
1432
1433
			// Delete safecss option
1434
			delete_option( 'safecss' );
1435
		}
1436
1437
		unset( $css );
1438
1439
		// Check if we have already done this
1440
		if ( !get_option( 'safecss_revision_migrated' ) ) {
1441
			define( 'DOING_MIGRATE', true );
1442
1443
			// Get hashes of safecss post and current revision
1444
			$safecss_post = Jetpack_Custom_CSS::get_post();
1445
1446
			if ( empty( $safecss_post ) )
1447
				return;
1448
1449
			$safecss_post_hash = md5( $safecss_post['post_content'] );
1450
			$current_revision = Jetpack_Custom_CSS::get_current_revision();
1451
1452
			if ( null == $current_revision )
1453
				return;
1454
1455
			$current_revision_hash = md5( $current_revision['post_content'] );
1456
1457
			// If hashes are not equal, set safecss post with content from current revision
1458
			if ( $safecss_post_hash !== $current_revision_hash ) {
1459
				Jetpack_Custom_CSS::save_revision( $current_revision['post_content'] );
1460
				// Reset post_content to display the migrated revsion
1461
				$safecss_post['post_content'] = $current_revision['post_content'];
1462
			}
1463
1464
			// Set option so that we dont keep doing this
1465
			update_option( 'safecss_revision_migrated', time() );
1466
		}
1467
1468
		$newest_safecss_post = Jetpack_Custom_CSS::get_current_revision();
1469
1470
		if ( $newest_safecss_post ) {
1471 View Code Duplication
			if ( get_option( 'safecss_content_width' ) ) {
1472
				// Add the meta to the post and the latest revision.
1473
				update_post_meta( $newest_safecss_post['ID'], 'content_width', get_option( 'safecss_content_width' ) );
1474
				update_metadata( 'post', $newest_safecss_post['ID'], 'content_width', get_option( 'safecss_content_width' ) );
1475
1476
				delete_option( 'safecss_content_width' );
1477
			}
1478
1479 View Code Duplication
			if ( get_option( 'safecss_add' ) ) {
1480
				update_post_meta( $newest_safecss_post['ID'], 'custom_css_add', get_option( 'safecss_add' ) );
1481
				update_metadata( 'post', $newest_safecss_post['ID'], 'custom_css_add', get_option( 'safecss_add' ) );
1482
1483
				delete_option( 'safecss_add' );
1484
			}
1485
		}
1486
	}
1487
1488
	/**
1489
	 * Adds a filter to the redirect location in `wp-admin/revisions.php`.
1490
	 */
1491
	static function add_revision_redirect() {
1492
		add_filter( 'wp_redirect', array( __CLASS__, 'revision_redirect' ) );
1493
	}
1494
1495
	/**
1496
	 * Filters the redirect location in `wp-admin/revisions.php`.
1497
	 *
1498
	 * @param string $location The path to redirect to.
1499
	 * @return string
1500
	 */
1501
	static function revision_redirect( $location ) {
1502
		$post = get_post();
1503
1504
		if ( ! empty( $post->post_type ) && 'safecss' == $post->post_type ) {
1505
			$location = 'themes.php?page=editcss';
1506
1507
			if ( 'edit.php' == $location ) {
1508
				$location = '';
1509
			}
1510
		}
1511
1512
		return $location;
1513
	}
1514
1515
	static function revision_post_link( $post_link, $post_id, $context ) {
1516
		if ( !$post_id = (int) $post_id ) {
1517
			return $post_link;
1518
		}
1519
1520
		if ( !$post = get_post( $post_id ) ) {
1521
			return $post_link;
1522
		}
1523
1524
		if ( 'safecss' != $post->post_type ) {
1525
			return $post_link;
1526
		}
1527
1528
		$post_link = admin_url( 'themes.php?page=editcss' );
1529
1530
		if ( 'display' == $context ) {
1531
			return esc_url( $post_link );
1532
		}
1533
1534
		return esc_url_raw( $post_link );
1535
	}
1536
1537
	/**
1538
	 * When on the edit screen, make sure the custom content width
1539
	 * setting is applied to the large image size.
1540
	 */
1541 View Code Duplication
	static function editor_max_image_size( $dims, $size = 'medium', $context = null ) {
1542
		list( $width, $height ) = $dims;
1543
1544
		if ( 'large' == $size && 'edit' == $context )
1545
			$width = Jetpack::get_content_width();
1546
1547
		return array( $width, $height );
1548
	}
1549
1550
	/**
1551
	 * Override the content_width with a custom value if one is set.
1552
	 */
1553
	static function jetpack_content_width( $content_width ) {
1554
		$custom_content_width = 0;
1555
1556
		if ( Jetpack_Custom_CSS::is_preview() ) {
1557
			$safecss_post = Jetpack_Custom_CSS::get_current_revision();
1558
			$custom_content_width = intval( get_post_meta( $safecss_post['ID'], 'content_width', true ) );
1559
		} else if ( ! Jetpack_Custom_CSS::is_freetrial() ) {
1560
			$custom_css_post_id = Jetpack_Custom_CSS::post_id();
1561
			if ( $custom_css_post_id )
1562
				$custom_content_width = intval( get_post_meta( $custom_css_post_id, 'content_width', true ) );
1563
		}
1564
1565
		if ( $custom_content_width > 0 )
1566
			$content_width = $custom_content_width;
1567
1568
		return $content_width;
1569
	}
1570
}
1571
1572
class Jetpack_Safe_CSS {
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...
1573
	static function filter_attr( $css, $element = 'div' ) {
1574
		safecss_class();
1575
1576
		$css = $element . ' {' . $css . '}';
1577
1578
		$csstidy = new csstidy();
1579
		$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...
1580
		$csstidy->set_cfg( 'remove_bslash', false );
1581
		$csstidy->set_cfg( 'compress_colors', false );
1582
		$csstidy->set_cfg( 'compress_font-weight', false );
1583
		$csstidy->set_cfg( 'discard_invalid_properties', true );
1584
		$csstidy->set_cfg( 'merge_selectors', false );
1585
		$csstidy->set_cfg( 'remove_last_;', false );
1586
		$csstidy->set_cfg( 'css_level', 'CSS3.0' );
1587
1588
		$css = preg_replace( '/\\\\([0-9a-fA-F]{4})/', '\\\\\\\\$1', $css );
1589
		$css = wp_kses_split( $css, array(), array() );
1590
		$csstidy->parse( $css );
1591
1592
		$css = $csstidy->print->plain();
1593
1594
		$css = str_replace( array( "\n","\r","\t" ), '', $css );
1595
1596
		preg_match( "/^{$element}\s*{(.*)}\s*$/", $css, $matches );
1597
1598
		if ( empty( $matches[1] ) )
1599
			return '';
1600
1601
		return $matches[1];
1602
	}
1603
}
1604
1605
function migrate() {
1606
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::upgrade()' );
1607
1608
	return Jetpack_Custom_CSS::upgrade();
1609
}
1610
1611
function safecss_revision_redirect( $redirect ) {
1612
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::revision_redirect()' );
1613
1614
	return Jetpack_Custom_CSS::revision_redirect( $redirect );
1615
}
1616
1617
function safecss_revision_post_link( $post_link, $post_id, $context ) {
1618
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::revision_post_link()' );
1619
1620
	return Jetpack_Custom_CSS::revision_post_link( $post_link, $post_id, $context );
1621
}
1622
1623
function get_safecss_post() {
1624
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::get_post()' );
1625
1626
	return Jetpack_Custom_CSS::get_post();
1627
}
1628
1629
function custom_css_post_id() {
1630
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::post_id()' );
1631
1632
	return Jetpack_Custom_CSS::post_id();
1633
}
1634
1635
function get_current_revision() {
1636
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::get_current_revision()' );
1637
1638
	return Jetpack_Custom_CSS::get_current_revision();
1639
}
1640
1641
function save_revision( $css, $is_preview = false, $preprocessor = '' ) {
1642
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::save_revision()' );
1643
1644
	return Jetpack_Custom_CSS::save_revision( $css, $is_preview, $preprocessor );
1645
}
1646
1647
function safecss_skip_stylesheet() {
1648
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::skip_stylesheet()' );
1649
1650
	return Jetpack_Custom_CSS::skip_stylesheet();
1651
}
1652
1653
function safecss_init() {
1654
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::init()' );
1655
1656
	return Jetpack_Custom_CSS::init();
1657
}
1658
1659
function safecss_is_preview() {
1660
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::is_preview()' );
1661
1662
	return Jetpack_Custom_CSS::is_preview();
1663
}
1664
1665
function safecss_is_freetrial() {
1666
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::is_freetrial()' );
1667
1668
	return Jetpack_Custom_CSS::is_freetrial();
1669
}
1670
1671
function safecss( $compressed = false ) {
1672
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::get_css()' );
1673
1674
	return Jetpack_Custom_CSS::get_css( $compressed );
1675
}
1676
1677
function safecss_print() {
1678
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::print_css()' );
1679
1680
	return Jetpack_Custom_CSS::print_css();
1681
}
1682
1683
function safecss_style() {
1684
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::link_tag()' );
1685
1686
	return Jetpack_Custom_CSS::link_tag();
1687
}
1688
1689
function safecss_style_filter( $current ) {
1690
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::style_filter()' );
1691
1692
	return Jetpack_Custom_CSS::style_filter( $current );
1693
}
1694
1695
function safecss_buffer( $html ) {
1696
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::buffer()' );
1697
1698
	return Jetpack_Custom_CSS::buffer( $html );
1699
}
1700
1701
function safecss_preview_links( $matches ) {
1702
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::preview_links()' );
1703
1704
	return Jetpack_Custom_CSS::preview_links( $matches );
1705
}
1706
1707
function safecss_preview_flag() {
1708
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::preview_flag()' );
1709
1710
	return Jetpack_Custom_CSS::preview_flag();
1711
}
1712
1713
function safecss_menu() {
1714
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::menu()' );
1715
1716
	return Jetpack_Custom_CSS::menu();
1717
}
1718
1719
function update_title() {
1720
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::update_title()' );
1721
1722
	return Jetpack_Custom_CSS::update_title();
1723
}
1724
1725
function safecss_prettify_post_revisions() {
1726
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::prettify_post_revisions()' );
1727
1728
	return Jetpack_Custom_CSS::prettify_post_revisions();
1729
}
1730
1731
function safecss_remove_title_excerpt_from_revisions() {
1732
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::remove_title_excerpt_from_revisions()' );
1733
1734
	return Jetpack_Custom_CSS::remove_title_excerpt_from_revisions();
0 ignored issues
show
Bug introduced by
The method remove_title_excerpt_from_revisions() does not seem to exist on object<Jetpack_Custom_CSS>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1735
}
1736
1737
function safecss_post_title( $title, $post_id ) {
1738
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::post_title()' );
1739
1740
	return Jetpack_Custom_CSS::post_title( $title, $post_id );
1741
}
1742
1743
function safe_css_enqueue_scripts() {
1744
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::enqueue_scripts()' );
1745
1746
	return Jetpack_Custom_CSS::enqueue_scripts();
0 ignored issues
show
Bug introduced by
The call to enqueue_scripts() misses a required argument $hook.

This check looks for function calls that miss required arguments.

Loading history...
1747
}
1748
1749
function safecss_admin_head() {
1750
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::admin_head()' );
1751
1752
	return Jetpack_Custom_CSS::admin_head();
0 ignored issues
show
Bug introduced by
The method admin_head() does not seem to exist on object<Jetpack_Custom_CSS>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1753
}
1754
1755
function safecss_saved() {
1756
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::saved_message()' );
1757
1758
	return Jetpack_Custom_CSS::saved_message();
1759
}
1760
1761
function safecss_admin() {
1762
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::admin()' );
1763
1764
	return Jetpack_Custom_CSS::admin();
1765
}
1766
1767
function custom_css_meta_box() {
1768
	_deprecated_function( __FUNCTION__, '2.1', 'add_meta_box( $id, $title, $callback, \'editcss\', \'side\' )' );
1769
}
1770
1771
function custom_css_post_revisions_meta_box( $safecss_post ) {
1772
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::revisions_meta_box()' );
1773
1774
	return Jetpack_Custom_CSS::revisions_meta_box( $safecss_post );
1775
}
1776
1777
function disable_safecss_style() {
1778
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::disable()' );
1779
1780
	return Jetpack_Custom_CSS::disable();
1781
}
1782
1783
function custom_css_reset() {
1784
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::reset()' );
1785
1786
	return Jetpack_Custom_CSS::reset();
1787
}
1788
1789
function custom_css_is_customizer_preview() {
1790
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::is_customizer_preview()' );
1791
1792
	return Jetpack_Custom_CSS::is_customizer_preview();
1793
}
1794
1795
function custom_css_minify( $css, $preprocessor = '' ) {
1796
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::minify()' );
1797
1798
	return Jetpack_Custom_CSS::minify( $css, $preprocessor );
1799
}
1800
1801
function custom_css_restore_revision( $_post_id, $_revision_id ) {
1802
	_deprecated_function( __FUNCTION__, '2.1', 'Jetpack_Custom_CSS::restore_revision()' );
1803
1804
	return Jetpack_Custom_CSS::restore_revision( $_post_id, $_revision_id );
1805
}
1806
1807 View Code Duplication
if ( ! function_exists( 'safecss_class' ) ) :
1808
function safecss_class() {
0 ignored issues
show
Best Practice introduced by
The function safecss_class() has been defined more than once; this definition is ignored, only the first definition in modules/custom-css/custom-css-4.7.php (L1102-1137) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
1809
	// Wrapped so we don't need the parent class just to load the plugin
1810
	if ( class_exists('safecss') )
1811
		return;
1812
1813
	require_once( dirname( __FILE__ ) . '/csstidy/class.csstidy.php' );
1814
1815
	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...
Comprehensibility Best Practice introduced by
The type safecss has been defined more than once; this definition is ignored, only the first definition in modules/custom-css/custom-css-4.7.php (L1113-1136) is considered.

This check looks for classes that have been defined more than once.

If you can, we would recommend to use standard object-oriented programming techniques. For example, to avoid multiple types, it might make sense to create a common interface, and then multiple, different implementations for that interface.

This also has the side-effect of providing you with better IDE auto-completion, static analysis and also better OPCode caching from PHP.

Loading history...
1816
1817
		function postparse() {
1818
1819
			/**
1820
			 * Fires after parsing the css.
1821
			 *
1822
			 * @module custom-css
1823
			 *
1824
			 * @since 1.8.0
1825
			 *
1826
			 * @param obj $this CSSTidy object.
1827
			 */
1828
			do_action( 'csstidy_optimize_postparse', $this );
1829
1830
			return parent::postparse();
1831
		}
1832
1833
		function subvalue() {
1834
1835
			/**
1836
			 * Fires before optimizing the Custom CSS subvalue.
1837
			 *
1838
			 * @module custom-css
1839
			 *
1840
			 * @since 1.8.0
1841
			 *
1842
			 * @param obj $this CSSTidy object.
1843
			 **/
1844
			do_action( 'csstidy_optimize_subvalue', $this );
1845
1846
			return parent::subvalue();
1847
		}
1848
	}
1849
}
1850
endif;
1851
1852
if ( ! function_exists( 'safecss_filter_attr' ) ) {
1853
	function safecss_filter_attr( $css, $element = 'div' ) {
1854
		return Jetpack_Safe_CSS::filter_attr( $css, $element );
1855
	}
1856
}
1857
1858
include_once dirname( __FILE__ ) . '/custom-css/preprocessors.php';
1859