Diff: STRATO-apps/wordpress_03/app/wp-admin/includes/class-theme-installer-skin.php

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
1 + <?php
2 + /**
3 + * Upgrader API: Theme_Installer_Skin class
4 + *
5 + * @package WordPress
6 + * @subpackage Upgrader
7 + * @since 4.6.0
8 + */
9 +
10 + /**
11 + * Theme Installer Skin for the WordPress Theme Installer.
12 + *
13 + * @since 2.8.0
14 + * @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader-skins.php.
15 + *
16 + * @see WP_Upgrader_Skin
17 + */
18 + class Theme_Installer_Skin extends WP_Upgrader_Skin {
19 + public $api;
20 + public $type;
21 + public $url;
22 + public $overwrite;
23 +
24 + private $is_downgrading = false;
25 +
26 + /**
27 + * Constructor.
28 + *
29 + * Sets up the theme installer skin.
30 + *
31 + * @since 2.8.0
32 + *
33 + * @param array $args
34 + */
35 + public function __construct( $args = array() ) {
36 + $defaults = array(
37 + 'type' => 'web',
38 + 'url' => '',
39 + 'theme' => '',
40 + 'nonce' => '',
41 + 'title' => '',
42 + 'overwrite' => '',
43 + );
44 + $args = wp_parse_args( $args, $defaults );
45 +
46 + $this->type = $args['type'];
47 + $this->url = $args['url'];
48 + $this->api = isset( $args['api'] ) ? $args['api'] : array();
49 + $this->overwrite = $args['overwrite'];
50 +
51 + parent::__construct( $args );
52 + }
53 +
54 + /**
55 + * Performs an action before installing a theme.
56 + *
57 + * @since 2.8.0
58 + */
59 + public function before() {
60 + if ( ! empty( $this->api ) ) {
61 + $this->upgrader->strings['process_success'] = sprintf(
62 + $this->upgrader->strings['process_success_specific'],
63 + $this->api->name,
64 + $this->api->version
65 + );
66 + }
67 + }
68 +
69 + /**
70 + * Hides the `process_failed` error when updating a theme by uploading a zip file.
71 + *
72 + * @since 5.5.0
73 + *
74 + * @param WP_Error $wp_error WP_Error object.
75 + * @return bool True if the error should be hidden, false otherwise.
76 + */
77 + public function hide_process_failed( $wp_error ) {
78 + if (
79 + 'upload' === $this->type &&
80 + '' === $this->overwrite &&
81 + $wp_error->get_error_code() === 'folder_exists'
82 + ) {
83 + return true;
84 + }
85 +
86 + return false;
87 + }
88 +
89 + /**
90 + * Performs an action following a single theme install.
91 + *
92 + * @since 2.8.0
93 + */
94 + public function after() {
95 + if ( $this->do_overwrite() ) {
96 + return;
97 + }
98 +
99 + if ( empty( $this->upgrader->result['destination_name'] ) ) {
100 + return;
101 + }
102 +
103 + $theme_info = $this->upgrader->theme_info();
104 + if ( empty( $theme_info ) ) {
105 + return;
106 + }
107 +
108 + $name = $theme_info->display( 'Name' );
109 + $stylesheet = $this->upgrader->result['destination_name'];
110 + $template = $theme_info->get_template();
111 +
112 + $activate_link = add_query_arg(
113 + array(
114 + 'action' => 'activate',
115 + 'template' => urlencode( $template ),
116 + 'stylesheet' => urlencode( $stylesheet ),
117 + ),
118 + admin_url( 'themes.php' )
119 + );
120 + $activate_link = wp_nonce_url( $activate_link, 'switch-theme_' . $stylesheet );
121 +
122 + $install_actions = array();
123 +
124 + if ( current_user_can( 'edit_theme_options' ) && ( $theme_info->is_block_theme() || current_user_can( 'customize' ) ) ) {
125 + if ( $theme_info->is_block_theme() ) {
126 + $customize_url = add_query_arg(
127 + array(
128 + 'wp_theme_preview' => urlencode( $stylesheet ),
129 + 'return' => urlencode( admin_url( 'web' === $this->type ? 'theme-install.php' : 'themes.php' ) ),
130 + ),
131 + admin_url( 'site-editor.php' )
132 + );
133 + } else {
134 + $customize_url = add_query_arg(
135 + array(
136 + 'theme' => urlencode( $stylesheet ),
137 + 'return' => urlencode( admin_url( 'web' === $this->type ? 'theme-install.php' : 'themes.php' ) ),
138 + ),
139 + admin_url( 'customize.php' )
140 + );
141 + }
142 +
143 + $install_actions['preview'] = sprintf(
144 + '<a href="%s" class="hide-if-no-customize load-customize">' .
145 + '<span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
146 + esc_url( $customize_url ),
147 + __( 'Live Preview' ),
148 + /* translators: Hidden accessibility text. %s: Theme name. */
149 + sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name )
150 + );
151 + }
152 +
153 + $install_actions['activate'] = sprintf(
154 + '<a href="%s" class="activatelink">' .
155 + '<span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>',
156 + esc_url( $activate_link ),
157 + _x( 'Activate', 'theme' ),
158 + /* translators: Hidden accessibility text. %s: Theme name. */
159 + sprintf( _x( 'Activate &#8220;%s&#8221;', 'theme' ), $name )
160 + );
161 +
162 + if ( is_network_admin() && current_user_can( 'manage_network_themes' ) ) {
163 + $install_actions['network_enable'] = sprintf(
164 + '<a href="%s" target="_parent">%s</a>',
165 + esc_url( wp_nonce_url( 'themes.php?action=enable&amp;theme=' . urlencode( $stylesheet ), 'enable-theme_' . $stylesheet ) ),
166 + __( 'Network Enable' )
167 + );
168 + }
169 +
170 + if ( 'web' === $this->type ) {
171 + $install_actions['themes_page'] = sprintf(
172 + '<a href="%s" target="_parent">%s</a>',
173 + self_admin_url( 'theme-install.php' ),
174 + __( 'Go to Theme Installer' )
175 + );
176 + } elseif ( current_user_can( 'switch_themes' ) || current_user_can( 'edit_theme_options' ) ) {
177 + $install_actions['themes_page'] = sprintf(
178 + '<a href="%s" target="_parent">%s</a>',
179 + self_admin_url( 'themes.php' ),
180 + __( 'Go to Themes page' )
181 + );
182 + }
183 +
184 + if ( ! $this->result || is_wp_error( $this->result ) || is_network_admin() || ! current_user_can( 'switch_themes' ) ) {
185 + unset( $install_actions['activate'], $install_actions['preview'] );
186 + } elseif ( get_option( 'template' ) === $stylesheet ) {
187 + unset( $install_actions['activate'] );
188 + }
189 +
190 + /**
191 + * Filters the list of action links available following a single theme installation.
192 + *
193 + * @since 2.8.0
194 + *
195 + * @param string[] $install_actions Array of theme action links.
196 + * @param object $api Object containing WordPress.org API theme data.
197 + * @param string $stylesheet Theme directory name.
198 + * @param WP_Theme $theme_info Theme object.
199 + */
200 + $install_actions = apply_filters( 'install_theme_complete_actions', $install_actions, $this->api, $stylesheet, $theme_info );
201 + if ( ! empty( $install_actions ) ) {
202 + $this->feedback( implode( ' | ', (array) $install_actions ) );
203 + }
204 + }
205 +
206 + /**
207 + * Checks if the theme can be overwritten and outputs the HTML for overwriting a theme on upload.
208 + *
209 + * @since 5.5.0
210 + *
211 + * @return bool Whether the theme can be overwritten and HTML was outputted.
212 + */
213 + private function do_overwrite() {
214 + if ( 'upload' !== $this->type || ! is_wp_error( $this->result ) || 'folder_exists' !== $this->result->get_error_code() ) {
215 + return false;
216 + }
217 +
218 + $folder = $this->result->get_error_data( 'folder_exists' );
219 + $folder = rtrim( $folder, '/' );
220 +
221 + $current_theme_data = false;
222 + $all_themes = wp_get_themes( array( 'errors' => null ) );
223 +
224 + foreach ( $all_themes as $theme ) {
225 + $stylesheet_dir = wp_normalize_path( $theme->get_stylesheet_directory() );
226 +
227 + if ( rtrim( $stylesheet_dir, '/' ) !== $folder ) {
228 + continue;
229 + }
230 +
231 + $current_theme_data = $theme;
232 + }
233 +
234 + $new_theme_data = $this->upgrader->new_theme_data;
235 +
236 + if ( ! $current_theme_data || ! $new_theme_data ) {
237 + return false;
238 + }
239 +
240 + echo '<h2 class="update-from-upload-heading">' . esc_html__( 'This theme is already installed.' ) . '</h2>';
241 +
242 + // Check errors for active theme.
243 + if ( is_wp_error( $current_theme_data->errors() ) ) {
244 + $this->feedback( 'current_theme_has_errors', $current_theme_data->errors()->get_error_message() );
245 + }
246 +
247 + $this->is_downgrading = version_compare( $current_theme_data['Version'], $new_theme_data['Version'], '>' );
248 +
249 + $is_invalid_parent = false;
250 + if ( ! empty( $new_theme_data['Template'] ) ) {
251 + $is_invalid_parent = ! in_array( $new_theme_data['Template'], array_keys( $all_themes ), true );
252 + }
253 +
254 + $rows = array(
255 + 'Name' => __( 'Theme name' ),
256 + 'Version' => __( 'Version' ),
257 + 'Author' => __( 'Author' ),
258 + 'RequiresWP' => __( 'Required WordPress version' ),
259 + 'RequiresPHP' => __( 'Required PHP version' ),
260 + 'Template' => __( 'Parent theme' ),
261 + );
262 +
263 + $table = '<table class="update-from-upload-comparison"><tbody>';
264 + $table .= '<tr><th></th><th>' . esc_html_x( 'Installed', 'theme' ) . '</th><th>' . esc_html_x( 'Uploaded', 'theme' ) . '</th></tr>';
265 +
266 + $is_same_theme = true; // Let's consider only these rows.
267 +
268 + foreach ( $rows as $field => $label ) {
269 + $old_value = $current_theme_data->display( $field, false );
270 + $old_value = $old_value ? (string) $old_value : '-';
271 +
272 + $new_value = ! empty( $new_theme_data[ $field ] ) ? (string) $new_theme_data[ $field ] : '-';
273 +
274 + if ( $old_value === $new_value && '-' === $new_value && 'Template' === $field ) {
275 + continue;
276 + }
277 +
278 + $is_same_theme = $is_same_theme && ( $old_value === $new_value );
279 +
280 + $diff_field = ( 'Version' !== $field && $new_value !== $old_value );
281 + $diff_version = ( 'Version' === $field && $this->is_downgrading );
282 + $invalid_parent = false;
283 +
284 + if ( 'Template' === $field && $is_invalid_parent ) {
285 + $invalid_parent = true;
286 + $new_value .= ' ' . __( '(not found)' );
287 + }
288 +
289 + $table .= '<tr><td class="name-label">' . $label . '</td><td>' . wp_strip_all_tags( $old_value ) . '</td>';
290 + $table .= ( $diff_field || $diff_version || $invalid_parent ) ? '<td class="warning">' : '<td>';
291 + $table .= wp_strip_all_tags( $new_value ) . '</td></tr>';
292 + }
293 +
294 + $table .= '</tbody></table>';
295 +
296 + /**
297 + * Filters the compare table output for overwriting a theme package on upload.
298 + *
299 + * @since 5.5.0
300 + *
301 + * @param string $table The output table with Name, Version, Author, RequiresWP, and RequiresPHP info.
302 + * @param WP_Theme $current_theme_data Active theme data.
303 + * @param array $new_theme_data Array with uploaded theme data.
304 + */
305 + echo apply_filters( 'install_theme_overwrite_comparison', $table, $current_theme_data, $new_theme_data );
306 +
307 + $install_actions = array();
308 + $can_update = true;
309 +
310 + $blocked_message = '<p>' . esc_html__( 'The theme cannot be updated due to the following:' ) . '</p>';
311 + $blocked_message .= '<ul class="ul-disc">';
312 +
313 + $requires_php = isset( $new_theme_data['RequiresPHP'] ) ? $new_theme_data['RequiresPHP'] : null;
314 + $requires_wp = isset( $new_theme_data['RequiresWP'] ) ? $new_theme_data['RequiresWP'] : null;
315 +
316 + if ( ! is_php_version_compatible( $requires_php ) ) {
317 + $error = sprintf(
318 + /* translators: 1: Current PHP version, 2: Version required by the uploaded theme. */
319 + __( 'The PHP version on your server is %1$s, however the uploaded theme requires %2$s.' ),
320 + PHP_VERSION,
321 + $requires_php
322 + );
323 +
324 + $blocked_message .= '<li>' . esc_html( $error ) . '</li>';
325 + $can_update = false;
326 + }
327 +
328 + if ( ! is_wp_version_compatible( $requires_wp ) ) {
329 + $error = sprintf(
330 + /* translators: 1: Current WordPress version, 2: Version required by the uploaded theme. */
331 + __( 'Your WordPress version is %1$s, however the uploaded theme requires %2$s.' ),
332 + esc_html( wp_get_wp_version() ),
333 + $requires_wp
334 + );
335 +
336 + $blocked_message .= '<li>' . esc_html( $error ) . '</li>';
337 + $can_update = false;
338 + }
339 +
340 + $blocked_message .= '</ul>';
341 +
342 + if ( $can_update ) {
343 + if ( $this->is_downgrading ) {
344 + $warning = sprintf(
345 + /* translators: %s: Documentation URL. */
346 + __( 'You are uploading an older version of the installed theme. You can continue to install the older version, but be sure to <a href="%s">back up your database and files</a> first.' ),
347 + __( 'https://developer.wordpress.org/advanced-administration/security/backup/' )
348 + );
349 + } else {
350 + $warning = sprintf(
351 + /* translators: %s: Documentation URL. */
352 + __( 'You are updating a theme. Be sure to <a href="%s">back up your database and files</a> first.' ),
353 + __( 'https://developer.wordpress.org/advanced-administration/security/backup/' )
354 + );
355 + }
356 +
357 + echo '<p class="update-from-upload-notice">' . $warning . '</p>';
358 +
359 + $overwrite = $this->is_downgrading ? 'downgrade-theme' : 'update-theme';
360 +
361 + $install_actions['overwrite_theme'] = sprintf(
362 + '<a class="button button-primary update-from-upload-overwrite" href="%s" target="_parent">%s</a>',
363 + wp_nonce_url( add_query_arg( 'overwrite', $overwrite, $this->url ), 'theme-upload' ),
364 + _x( 'Replace installed with uploaded', 'theme' )
365 + );
366 + } else {
367 + echo $blocked_message;
368 + }
369 +
370 + $cancel_url = add_query_arg( 'action', 'upload-theme-cancel-overwrite', $this->url );
371 +
372 + $install_actions['themes_page'] = sprintf(
373 + '<a class="button" href="%s" target="_parent">%s</a>',
374 + wp_nonce_url( $cancel_url, 'theme-upload-cancel-overwrite' ),
375 + __( 'Cancel and go back' )
376 + );
377 +
378 + /**
379 + * Filters the list of action links available following a single theme installation failure
380 + * when overwriting is allowed.
381 + *
382 + * @since 5.5.0
383 + *
384 + * @param string[] $install_actions Array of theme action links.
385 + * @param object $api Object containing WordPress.org API theme data.
386 + * @param array $new_theme_data Array with uploaded theme data.
387 + */
388 + $install_actions = apply_filters( 'install_theme_overwrite_actions', $install_actions, $this->api, $new_theme_data );
389 +
390 + if ( ! empty( $install_actions ) ) {
391 + printf(
392 + '<p class="update-from-upload-expired hidden">%s</p>',
393 + __( 'The uploaded file has expired. Please go back and upload it again.' )
394 + );
395 + echo '<p class="update-from-upload-actions">' . implode( ' ', (array) $install_actions ) . '</p>';
396 + }
397 +
398 + return true;
399 + }
400 + }
401 +