Completed
Push — try/merge-master-into-settings ( b008c5 )
by
unknown
53:52 queued 44:09
created

modules/custom-css/migrate-to-core.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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