Make WordPress Core

Ticket #64439: 64439-theme-editor.patch

File 64439-theme-editor.patch, 7.7 KB (added by solankisoftware, 2 months ago)

Fix :: Theme Editor Download button

  • wp-admin/theme-editor.php

     
    7777        wp_die( __( 'The requested theme does not exist.' ) . ' ' . $theme->errors()->get_error_message() );
    7878}
    7979
     80// Handle theme download action: create a zip of the theme and send it to the browser.
     81if ( 'download_theme' === $action ) {
     82        if ( ! current_user_can( 'edit_themes' ) ) {
     83                wp_die( '<p>' . __( 'Sorry, you are not allowed to download themes for this site.' ) . '</p>' );
     84        }
     85
     86        // Verify nonce (accept either _wpnonce or nonce parameter for compatibility).
     87        $nonce_name = isset( $_REQUEST['_wpnonce'] ) ? '_wpnonce' : 'nonce';
     88        if ( ! check_admin_referer( 'download-theme_' . $stylesheet, $nonce_name, false ) ) {
     89                wp_die( '<p>' . __( 'Security check failed.' ) . '</p>' );
     90        }
     91
     92        $theme_dir = $theme->get_stylesheet_directory();
     93
     94        if ( ! is_dir( $theme_dir ) ) {
     95                wp_die( '<p>' . __( 'Theme directory not found.' ) . '</p>' );
     96        }
     97
     98        $zipname = sanitize_file_name( $theme->get( 'Name' ) );
     99        if ( ! $zipname ) {
     100                $zipname = $stylesheet;
     101        }
     102        $tmpfile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $zipname . '-' . time() . '.zip';
     103
     104        // Try native ZipArchive first, fall back to PclZip if needed.
     105        if ( class_exists( 'ZipArchive' ) ) {
     106                $zip = new ZipArchive();
     107                if ( true !== $zip->open( $tmpfile, ZipArchive::CREATE ) ) {
     108                        wp_die( '<p>' . __( 'Could not create zip archive.' ) . '</p>' );
     109                }
     110
     111                $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $theme_dir ) );
     112                foreach ( $files as $file ) {
     113                        if ( $file->isDir() ) {
     114                                continue;
     115                        }
     116                        $filePath = $file->getRealPath();
     117                        $relativePath = substr( $filePath, strlen( $theme_dir ) + 1 );
     118                        $zip->addFile( $filePath, $relativePath );
     119                }
     120
     121                $zip->close();
     122        } else {
     123                // Use PclZip fallback bundled with WordPress admin.
     124                require_once ABSPATH . 'wp-admin/includes/class-pclzip.php';
     125
     126                $filelist = array();
     127                $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $theme_dir ) );
     128                foreach ( $files as $file ) {
     129                        if ( $file->isDir() ) {
     130                                continue;
     131                        }
     132                        $filelist[] = $file->getRealPath();
     133                }
     134
     135                $archive = new PclZip( $tmpfile );
     136                $result = $archive->create( $filelist, PCLZIP_OPT_REMOVE_PATH, $theme_dir );
     137                if ( 0 === $result ) {
     138                        wp_die( '<p>' . __( 'Could not create zip archive.' ) . ' ' . esc_html( $archive->errorInfo( true ) ) . '</p>' );
     139                }
     140        }
     141
     142        if ( ! file_exists( $tmpfile ) ) {
     143                wp_die( '<p>' . __( 'Failed to create theme archive.' ) . '</p>' );
     144        }
     145
     146        // Send the file to the browser.
     147        header( 'Content-Type: application/zip' );
     148        header( 'Content-Disposition: attachment; filename="' . $zipname . '.zip"' );
     149        header( 'Content-Length: ' . filesize( $tmpfile ) );
     150        readfile( $tmpfile );
     151        @unlink( $tmpfile );
     152        exit;
     153}
     154
    80155$allowed_files = array();
    81156$style_files   = array();
    82157
     
    304379                </select>
    305380                <?php submit_button( __( 'Select' ), '', 'Submit', false ); ?>
    306381        </form>
     382
     383        <!-- Download Theme button moved below the editor to avoid cluttering the theme selector. -->
    307384</div>
    308385<br class="clear" />
    309386</div>
     
    415492
    416493                <?php wp_print_file_editor_templates(); ?>
    417494        </form>
     495
     496        <!-- Download Theme form placed below the Update File button -->
     497        <form action="theme-editor.php" method="post" style="margin-top:8px;">
     498                <?php wp_nonce_field( 'download-theme_' . $stylesheet, '_wpnonce' ); ?>
     499                <input type="hidden" name="action" value="download_theme" />
     500                <input type="hidden" name="theme" value="<?php echo esc_attr( $stylesheet ); ?>" />
     501                <?php submit_button( __( 'Download Theme' ), 'secondary', '', false ); ?>
     502        </form>
    418503        <?php
    419504endif; // End if $error.
    420505?>