[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
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' ) && current_user_can( 'customize' ) && ! $theme_info->is_block_theme() ) { 125 $customize_url = add_query_arg( 126 array( 127 'theme' => urlencode( $stylesheet ), 128 'return' => urlencode( admin_url( 'web' === $this->type ? 'theme-install.php' : 'themes.php' ) ), 129 ), 130 admin_url( 'customize.php' ) 131 ); 132 133 $install_actions['preview'] = sprintf( 134 '<a href="%s" class="hide-if-no-customize load-customize">' . 135 '<span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>', 136 esc_url( $customize_url ), 137 __( 'Live Preview' ), 138 /* translators: Hidden accessibility text. %s: Theme name. */ 139 sprintf( __( 'Live Preview “%s”' ), $name ) 140 ); 141 } 142 143 $install_actions['activate'] = sprintf( 144 '<a href="%s" class="activatelink">' . 145 '<span aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>', 146 esc_url( $activate_link ), 147 _x( 'Activate', 'theme' ), 148 /* translators: Hidden accessibility text. %s: Theme name. */ 149 sprintf( _x( 'Activate “%s”', 'theme' ), $name ) 150 ); 151 152 if ( is_network_admin() && current_user_can( 'manage_network_themes' ) ) { 153 $install_actions['network_enable'] = sprintf( 154 '<a href="%s" target="_parent">%s</a>', 155 esc_url( wp_nonce_url( 'themes.php?action=enable&theme=' . urlencode( $stylesheet ), 'enable-theme_' . $stylesheet ) ), 156 __( 'Network Enable' ) 157 ); 158 } 159 160 if ( 'web' === $this->type ) { 161 $install_actions['themes_page'] = sprintf( 162 '<a href="%s" target="_parent">%s</a>', 163 self_admin_url( 'theme-install.php' ), 164 __( 'Go to Theme Installer' ) 165 ); 166 } elseif ( current_user_can( 'switch_themes' ) || current_user_can( 'edit_theme_options' ) ) { 167 $install_actions['themes_page'] = sprintf( 168 '<a href="%s" target="_parent">%s</a>', 169 self_admin_url( 'themes.php' ), 170 __( 'Go to Themes page' ) 171 ); 172 } 173 174 if ( ! $this->result || is_wp_error( $this->result ) || is_network_admin() || ! current_user_can( 'switch_themes' ) ) { 175 unset( $install_actions['activate'], $install_actions['preview'] ); 176 } elseif ( get_option( 'template' ) === $stylesheet ) { 177 unset( $install_actions['activate'] ); 178 } 179 180 /** 181 * Filters the list of action links available following a single theme installation. 182 * 183 * @since 2.8.0 184 * 185 * @param string[] $install_actions Array of theme action links. 186 * @param object $api Object containing WordPress.org API theme data. 187 * @param string $stylesheet Theme directory name. 188 * @param WP_Theme $theme_info Theme object. 189 */ 190 $install_actions = apply_filters( 'install_theme_complete_actions', $install_actions, $this->api, $stylesheet, $theme_info ); 191 if ( ! empty( $install_actions ) ) { 192 $this->feedback( implode( ' | ', (array) $install_actions ) ); 193 } 194 } 195 196 /** 197 * Checks if the theme can be overwritten and outputs the HTML for overwriting a theme on upload. 198 * 199 * @since 5.5.0 200 * 201 * @return bool Whether the theme can be overwritten and HTML was outputted. 202 */ 203 private function do_overwrite() { 204 if ( 'upload' !== $this->type || ! is_wp_error( $this->result ) || 'folder_exists' !== $this->result->get_error_code() ) { 205 return false; 206 } 207 208 $folder = $this->result->get_error_data( 'folder_exists' ); 209 $folder = rtrim( $folder, '/' ); 210 211 $current_theme_data = false; 212 $all_themes = wp_get_themes( array( 'errors' => null ) ); 213 214 foreach ( $all_themes as $theme ) { 215 $stylesheet_dir = wp_normalize_path( $theme->get_stylesheet_directory() ); 216 217 if ( rtrim( $stylesheet_dir, '/' ) !== $folder ) { 218 continue; 219 } 220 221 $current_theme_data = $theme; 222 } 223 224 $new_theme_data = $this->upgrader->new_theme_data; 225 226 if ( ! $current_theme_data || ! $new_theme_data ) { 227 return false; 228 } 229 230 echo '<h2 class="update-from-upload-heading">' . esc_html__( 'This theme is already installed.' ) . '</h2>'; 231 232 // Check errors for active theme. 233 if ( is_wp_error( $current_theme_data->errors() ) ) { 234 $this->feedback( 'current_theme_has_errors', $current_theme_data->errors()->get_error_message() ); 235 } 236 237 $this->is_downgrading = version_compare( $current_theme_data['Version'], $new_theme_data['Version'], '>' ); 238 239 $is_invalid_parent = false; 240 if ( ! empty( $new_theme_data['Template'] ) ) { 241 $is_invalid_parent = ! in_array( $new_theme_data['Template'], array_keys( $all_themes ), true ); 242 } 243 244 $rows = array( 245 'Name' => __( 'Theme name' ), 246 'Version' => __( 'Version' ), 247 'Author' => __( 'Author' ), 248 'RequiresWP' => __( 'Required WordPress version' ), 249 'RequiresPHP' => __( 'Required PHP version' ), 250 'Template' => __( 'Parent theme' ), 251 ); 252 253 $table = '<table class="update-from-upload-comparison"><tbody>'; 254 $table .= '<tr><th></th><th>' . esc_html_x( 'Active', 'theme' ) . '</th><th>' . esc_html_x( 'Uploaded', 'theme' ) . '</th></tr>'; 255 256 $is_same_theme = true; // Let's consider only these rows. 257 258 foreach ( $rows as $field => $label ) { 259 $old_value = $current_theme_data->display( $field, false ); 260 $old_value = $old_value ? (string) $old_value : '-'; 261 262 $new_value = ! empty( $new_theme_data[ $field ] ) ? (string) $new_theme_data[ $field ] : '-'; 263 264 if ( $old_value === $new_value && '-' === $new_value && 'Template' === $field ) { 265 continue; 266 } 267 268 $is_same_theme = $is_same_theme && ( $old_value === $new_value ); 269 270 $diff_field = ( 'Version' !== $field && $new_value !== $old_value ); 271 $diff_version = ( 'Version' === $field && $this->is_downgrading ); 272 $invalid_parent = false; 273 274 if ( 'Template' === $field && $is_invalid_parent ) { 275 $invalid_parent = true; 276 $new_value .= ' ' . __( '(not found)' ); 277 } 278 279 $table .= '<tr><td class="name-label">' . $label . '</td><td>' . wp_strip_all_tags( $old_value ) . '</td>'; 280 $table .= ( $diff_field || $diff_version || $invalid_parent ) ? '<td class="warning">' : '<td>'; 281 $table .= wp_strip_all_tags( $new_value ) . '</td></tr>'; 282 } 283 284 $table .= '</tbody></table>'; 285 286 /** 287 * Filters the compare table output for overwriting a theme package on upload. 288 * 289 * @since 5.5.0 290 * 291 * @param string $table The output table with Name, Version, Author, RequiresWP, and RequiresPHP info. 292 * @param WP_Theme $current_theme_data Active theme data. 293 * @param array $new_theme_data Array with uploaded theme data. 294 */ 295 echo apply_filters( 'install_theme_overwrite_comparison', $table, $current_theme_data, $new_theme_data ); 296 297 $install_actions = array(); 298 $can_update = true; 299 300 $blocked_message = '<p>' . esc_html__( 'The theme cannot be updated due to the following:' ) . '</p>'; 301 $blocked_message .= '<ul class="ul-disc">'; 302 303 $requires_php = isset( $new_theme_data['RequiresPHP'] ) ? $new_theme_data['RequiresPHP'] : null; 304 $requires_wp = isset( $new_theme_data['RequiresWP'] ) ? $new_theme_data['RequiresWP'] : null; 305 306 if ( ! is_php_version_compatible( $requires_php ) ) { 307 $error = sprintf( 308 /* translators: 1: Current PHP version, 2: Version required by the uploaded theme. */ 309 __( 'The PHP version on your server is %1$s, however the uploaded theme requires %2$s.' ), 310 PHP_VERSION, 311 $requires_php 312 ); 313 314 $blocked_message .= '<li>' . esc_html( $error ) . '</li>'; 315 $can_update = false; 316 } 317 318 if ( ! is_wp_version_compatible( $requires_wp ) ) { 319 $error = sprintf( 320 /* translators: 1: Current WordPress version, 2: Version required by the uploaded theme. */ 321 __( 'Your WordPress version is %1$s, however the uploaded theme requires %2$s.' ), 322 esc_html( wp_get_wp_version() ), 323 $requires_wp 324 ); 325 326 $blocked_message .= '<li>' . esc_html( $error ) . '</li>'; 327 $can_update = false; 328 } 329 330 $blocked_message .= '</ul>'; 331 332 if ( $can_update ) { 333 if ( $this->is_downgrading ) { 334 $warning = sprintf( 335 /* translators: %s: Documentation URL. */ 336 __( 'You are uploading an older version of the active theme. You can continue to install the older version, but be sure to <a href="%s">back up your database and files</a> first.' ), 337 __( 'https://developer.wordpress.org/advanced-administration/security/backup/' ) 338 ); 339 } else { 340 $warning = sprintf( 341 /* translators: %s: Documentation URL. */ 342 __( 'You are updating a theme. Be sure to <a href="%s">back up your database and files</a> first.' ), 343 __( 'https://developer.wordpress.org/advanced-administration/security/backup/' ) 344 ); 345 } 346 347 echo '<p class="update-from-upload-notice">' . $warning . '</p>'; 348 349 $overwrite = $this->is_downgrading ? 'downgrade-theme' : 'update-theme'; 350 351 $install_actions['overwrite_theme'] = sprintf( 352 '<a class="button button-primary update-from-upload-overwrite" href="%s" target="_parent">%s</a>', 353 wp_nonce_url( add_query_arg( 'overwrite', $overwrite, $this->url ), 'theme-upload' ), 354 _x( 'Replace active with uploaded', 'theme' ) 355 ); 356 } else { 357 echo $blocked_message; 358 } 359 360 $cancel_url = add_query_arg( 'action', 'upload-theme-cancel-overwrite', $this->url ); 361 362 $install_actions['themes_page'] = sprintf( 363 '<a class="button" href="%s" target="_parent">%s</a>', 364 wp_nonce_url( $cancel_url, 'theme-upload-cancel-overwrite' ), 365 __( 'Cancel and go back' ) 366 ); 367 368 /** 369 * Filters the list of action links available following a single theme installation failure 370 * when overwriting is allowed. 371 * 372 * @since 5.5.0 373 * 374 * @param string[] $install_actions Array of theme action links. 375 * @param object $api Object containing WordPress.org API theme data. 376 * @param array $new_theme_data Array with uploaded theme data. 377 */ 378 $install_actions = apply_filters( 'install_theme_overwrite_actions', $install_actions, $this->api, $new_theme_data ); 379 380 if ( ! empty( $install_actions ) ) { 381 printf( 382 '<p class="update-from-upload-expired hidden">%s</p>', 383 __( 'The uploaded file has expired. Please go back and upload it again.' ) 384 ); 385 echo '<p class="update-from-upload-actions">' . implode( ' ', (array) $install_actions ) . '</p>'; 386 } 387 388 return true; 389 } 390 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Nov 21 08:20:01 2024 | Cross-referenced by PHPXref |