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

Jetpack_Custom_CSS_Data_Migration::add_hooks()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 0
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
/**
3
 * Migration from Jetpack Custom CSS to WordPress' Core CSS.
4
 *
5
 * @since 4.4.2
6
 *
7
 * @package Jetpack
8
 */
9
10
/**
11
 * Class Jetpack_Custom_CSS_Data_Migration
12
 */
13
class Jetpack_Custom_CSS_Data_Migration {
14
	/**
15
	 * Set up assorted actions and filters used by this class.
16
	 */
17
	public static function add_hooks() {
18
		add_action( 'init', array( __CLASS__, 'register_legacy_post_type' ) );
19
		add_action( 'admin_init', array( __CLASS__, 'do_migration' ) );
20
21
		include_once( dirname( __FILE__ ) . '/custom-css.php' );
22
		if ( ! is_admin() ) {
23
			add_action( 'init', array( 'Jetpack_Custom_CSS', 'init' ) );
24
		}
25
	}
26
27
	/**
28
	 * Do the bulk of the migration.
29
	 *
30
	 * @return int|null
31
	 */
32
	public static function do_migration() {
33
		Jetpack_Options::update_option( 'custom_css_4.7_migration', true );
34
		Jetpack::log( 'custom_css_4.7_migration', 'start' );
35
36
		if ( ! post_type_exists( 'safecss' ) ) {
37
			self::register_legacy_post_type();
38
		}
39
40
		/** This filter is documented in modules/custom-css/custom-css.php */
41
		$preprocessors      = apply_filters( 'jetpack_custom_css_preprocessors', array() );
42
		$core_css_post      = wp_get_custom_css_post();
43
		$jetpack_css_post   = self::get_post();
44
45
		if ( ! $jetpack_css_post ) {
46
			return;
47
		}
48
49
		$revisions          = self::get_all_revisions();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 10 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
50
51
		// Migrate the settings from revision meta to theme mod.
52
		$options = self::get_options( $jetpack_css_post->ID );
53
		set_theme_mod( 'jetpack_custom_css', $options );
54
55
		if ( empty( $revisions ) || ! is_array( $revisions ) ) {
56
			if ( $jetpack_css_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...
57
				// Feed in the raw, if the current setting is Sass/LESS, it'll filter it inside.
58
				kses_remove_filters();
59
				wp_update_custom_css_post( $jetpack_css_post->post_content );
60
				kses_init();
61
				return 1;
62
			}
63
			return null;
64
		}
65
66
		$revisions            = array_reverse( $revisions );
67
		$themes               = Jetpack_Custom_CSS_Enhancements::get_themes();
68
		$migrated             = array();
69
70
		foreach ( $revisions as $post_id => $post ) {
71
			// Jetpack had stored the theme Name, not the stylesheet directory, for ... reasons.
72
			// Get the stylesheet.  If null, the theme is no longer available.  Skip.
73
			$stylesheet = isset( $themes[ $post->post_excerpt ] ) ? $themes[ $post->post_excerpt ] : null;
74
			if ( empty( $stylesheet ) ) {
75
				continue;
76
			}
77
78
			$migrated[] = $post->ID;
79
			$preprocessor = get_post_meta( $post->ID, 'custom_css_preprocessor', true );
80
			$css = $post->post_content;
81
			$pre = '';
82
83
			// Do a revision by revision parsing.
84
			if ( $preprocessor && isset( $preprocessors[ $preprocessor ] ) ) {
85
				$pre = $css;
86
				$css = call_user_func( $preprocessors[ $preprocessor ]['callback'], $pre );
87
			}
88
89
			kses_remove_filters();
90
			wp_update_custom_css_post( $css, array(
91
				'stylesheet'   => $stylesheet,
92
				'preprocessed' => $pre,
93
			) );
94
			kses_init();
95
		}
96
97
		// If we've migrated some CSS for the current theme and there was already something there in the Core dataset ...
98
		if ( $core_css_post && $jetpack_css_post ) {
99
			$preprocessor = $options['preprocessor'];
100
101
			$css = $core_css_post->post_content;
102
			$pre = $core_css_post->post_content_filtered;
103
			if ( $preprocessor ) {
104
				if ( $pre ) {
105
					$pre .= "\r\n\r\n/*\r\n\t" . esc_js( __( 'CSS Migrated from Jetpack:', 'jetpack' ) ) . "\r\n*/\r\n\r\n";
106
				}
107
				$pre .= $jetpack_css_post->post_content;
108
109
				$css .= "\r\n\r\n/*\r\n\t" . esc_js( __( 'CSS Migrated from Jetpack:', 'jetpack' ) ) . "\r\n*/\r\n\r\n";
110
				$css .= call_user_func( $preprocessors[ $preprocessor ]['callback'], $jetpack_css_post->post_content );
111
			} else {
112
				$css .= "\r\n\r\n/*\r\n\t" . esc_js( __( 'CSS Migrated from Jetpack:', 'jetpack' ) ) . "\r\n*/\r\n\r\n";
113
				$css .= $jetpack_css_post->post_content;
114
			}
115
116
			wp_update_custom_css_post( $css, array(
117
				'preprocessed' => $pre,
118
			) );
119
		}
120
121
		Jetpack::log( 'custom_css_4.7_migration', count( $migrated ) . 'revisions migrated' );
122
		return count( $migrated );
123
	}
124
125
	/**
126
	 * Re-register the legacy CPT so we can play with the content already in the database.
127
	 */
128
	public static function register_legacy_post_type() {
129
		if ( post_type_exists( 'safecss' ) ) {
130
			return;
131
		}
132
		// Register safecss as a custom post_type
133
		// 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.
134
		register_post_type( 'safecss', array(
135
			'label'        => 'Custom CSS',
136
			'supports'     => array( 'revisions' ),
137
			'can_export'   => false,
138
			'rewrite'      => false,
139
			'capabilities' => array(
140
				'edit_post'          => 'edit_theme_options',
141
				'read_post'          => 'read',
142
				'delete_post'        => 'edit_theme_options',
143
				'edit_posts'         => 'edit_theme_options',
144
				'edit_others_posts'  => 'edit_theme_options',
145
				'publish_posts'      => 'edit_theme_options',
146
				'read_private_posts' => 'read',
147
			),
148
		) );
149
	}
150
151
	/**
152
	 * Get the post used for legacy storage.
153
	 *
154
	 * Jetpack used to use a single post for all themes, just blanking it on theme switch.  This gets that post.
155
	 *
156
	 * @return array|bool|null|WP_Post
157
	 */
158 View Code Duplication
	public static function get_post() {
159
		/** This filter is documented in modules/custom-css/custom-css.php */
160
		$custom_css_post_id = apply_filters( 'jetpack_custom_css_pre_post_id', null );
161
		if ( ! is_null( $custom_css_post_id ) ) {
162
			return get_post( $custom_css_post_id );
163
		}
164
165
		$custom_css_post_id = wp_cache_get( 'custom_css_post_id' );
166
167
		if ( false === $custom_css_post_id ) {
168
			$custom_css_posts = get_posts( array(
169
				'posts_per_page' => 1,
170
				'post_type'      => 'safecss',
171
				'post_status'    => 'publish',
172
				'orderby'        => 'date',
173
				'order'          => 'DESC',
174
			) );
175
176
			$custom_css_post_id = 0;
177
			if ( count( $custom_css_posts ) > 0 ) {
178
				$custom_css_post_id = $custom_css_posts[0]->ID;
179
			}
180
181
			// Save post_id=0 to note that no safecss post exists.
182
			wp_cache_set( 'custom_css_post_id', $custom_css_post_id );
183
		}
184
185
		if ( ! $custom_css_post_id ) {
186
			return false;
187
		}
188
189
		return get_post( $custom_css_post_id );
190
	}
191
192
	/**
193
	 * Get all revisions of the Jetpack CSS CPT entry.
194
	 *
195
	 * @return array
196
	 */
197
	public static function get_all_revisions() {
198
		$post = self::get_post();
199
200
		if ( ! $post ) {
201
			return array();
202
		}
203
204
		$revisions = wp_get_post_revisions( $post->ID, array(
205
			'posts_per_page' => -1,
206
			'orderby'        => 'date',
207
			'order'          => 'DESC',
208
		) );
209
210
		return $revisions;
211
	}
212
213
	/**
214
	 * Get the options stored for a given revision ID.
215
	 *
216
	 * Jetpack used to version the settings by storing them as meta on the revision.
217
	 *
218
	 * @param integer $post_id Post ID.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $post_id not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
219
	 *
220
	 * @return array
221
	 */
222
	public static function get_options( $post_id = null ) {
223
		if ( empty( $post_id ) ) {
224
			$post = self::get_post();
225
			$post_id = $post->ID;
226
		}
227
228
		$meta = get_post_meta( $post_id );
229
230
		$replace = false;
231
		if ( isset( $meta['custom_css_add'][0] ) && 'no' === $meta['custom_css_add'][0] ) {
232
			$replace = true;
233
		}
234
235
		return array(
236
			'preprocessor'  => isset( $meta['custom_css_preprocessor'][0] ) ? $meta['custom_css_preprocessor'][0] : '',
237
			'replace'       => $replace,
238
			'content_width' => isset( $meta['content_width'][0] )           ? $meta['content_width'][0]           : '',
239
		);
240
	}
241
}
242
243
Jetpack_Custom_CSS_Data_Migration::add_hooks();
244