Making WordPress.org

Changeset 12975


Ignore:
Timestamp:
11/22/2023 06:44:21 AM (14 months ago)
Author:
tellyworth
Message:

Plugin directory: supporting code for blueprint files.

This adds support for a new assets/blueprints folder.

Required for #7251.

Location:
sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/class-template.php

    r12933 r12975  
    723723
    724724    /**
     725     * Is a live preview available for the plugin, and allowed for the current user to view?
     726     *
     727     * @param int|\WP_Post|null $post    Optional. Post ID or post object. Defaults to global $post.
     728     * @return bool True if a preview is available and the current user is permitted to see it.
     729     */
     730    public static function is_preview_available( $post = null ) {
     731
     732        if ( self::preview_link( $post ) ) {
     733            // Plugin committers can always use the plugin preview button if it exists.
     734            if ( current_user_can( 'plugin_admin_edit', $post ) ) {
     735                return true;
     736            }
     737        }
     738        return false;
     739    }
     740
     741    /**
    725742     * Generate a live preview (playground) link for a given plugin.
    726743     *
    727744     * @param int|\WP_Post|null $post    Optional. Post ID or post object. Defaults to global $post.
    728      * @param string            $landing_page The landing page for the preview. Option. Default: /wp-admin/plugins.php.
    729      * @return string The preview url.
    730      */
    731     public static function preview_link( $post = null, $landing_page = '/wp-admin/plugins.php' ) {
     745     * @return false|string The preview url. False if no preview is configured.
     746     */
     747    public static function preview_link( $post = null ) {
    732748        $post = get_post( $post );
    733749
    734         return sprintf( 'https://playground.wordpress.net/?plugin=%s&login=1&url=%s', esc_attr( $post->post_name ), esc_attr( $landing_page ) );
     750        $blueprints = get_post_meta( $post->ID, 'assets_blueprints', true );
     751        // Note: for now, only use a file called `blueprint.json`.
     752        if ( !isset( $blueprints['blueprint.json'] ) ) {
     753            return false;
     754        }
     755        $blueprint = $blueprints['blueprint.json'];
     756        if ( !$blueprint || !isset( $blueprint['contents'] ) || !is_string( $blueprint['contents'] ) ) {
     757            return false;
     758        }
     759
     760        $blueprint_encoded = esc_html( $blueprint['contents'] );
     761
     762        return sprintf( 'https://playground.wordpress.net/?plugin=%s#%s', $post->post_name, $blueprint_encoded );
    735763    }
    736764
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/cli/class-import.php

    r12846 r12975  
    337337        update_post_meta( $plugin->ID, 'assets_banners_color', wp_slash( $banner_average_color ) );
    338338
     339        // Store the content of blueprint files, if they're available and valid.
     340        if ( isset( $assets['blueprint'] ) ) {
     341            update_post_meta( $plugin->ID, 'assets_blueprints', wp_slash( $assets['blueprint'] ) );
     342        } else {
     343            delete_post_meta( $plugin->ID, 'assets_blueprints' );
     344        }
     345
    339346        // Store the block data, if known
    340347        if ( count( $blocks ) ) {
     
    565572
    566573        if ( ! $svn_info || ! $svn_info['result'] ) {
    567             $stable_tag = 'trunk';
    568             $stable_url = self::PLUGIN_SVN_BASE . "/{$plugin_slug}/trunk";
    569             $svn_info   = SVN::info( $stable_url );
    570         }
    571 
    572         if ( ! $svn_info['result'] ) {
    573574            throw new Exception( 'Could not find stable SVN URL: ' . implode( ' ', reset( $svn_info['errors'] ) ) );
    574575        }
     
    614615            'banner'     => array(),
    615616            'icon'       => array(),
     617            'blueprint'  => array(),
    616618        );
    617619
     
    620622            'banner'     => 4 * MB_IN_BYTES,
    621623            'icon'       => 1 * MB_IN_BYTES,
     624            'blueprint'  => 100 * KB_IN_BYTES,
    622625        );
    623626
     627        $svn_blueprints_folder = null;
    624628        $svn_assets_folder = SVN::ls( self::PLUGIN_SVN_BASE . "/{$plugin_slug}/assets/", true /* verbose */ );
    625629        if ( $svn_assets_folder ) { // /assets/ may not exist.
    626630            foreach ( $svn_assets_folder as $asset ) {
     631                if ( 'blueprints' === $asset['filename'] ) {
     632                    $svn_blueprints_folder = self::PLUGIN_SVN_BASE . "/{$plugin_slug}/assets/blueprints/";
     633                    continue;
     634                }
     635
    627636                // screenshot-0(-rtl)(-de_DE).(png|jpg|jpeg|gif) || banner-772x250.PNG || icon.svg
    628637                if ( ! preg_match( '!^(?P<type>screenshot|banner|icon)(?:-(?P<resolution>\d+(?:\D\d+)?)(-rtl)?(?:-(?P<locale>[a-z]{2,3}(?:_[A-Z]{2})?(?:_[a-z0-9]+)?))?\.(png|jpg|jpeg|gif)|\.svg)$!iu', $asset['filename'], $m ) ) {
     
    652661
    653662                $assets[ $type ][ $asset['filename'] ] = compact( 'filename', 'revision', 'resolution', 'location', 'locale' );
     663            }
     664        }
     665
     666        if ( $svn_blueprints_folder ) {
     667            $svn_export = SVN::export(
     668                $svn_blueprints_folder,
     669                $tmp_dir . '/blueprints',
     670                array(
     671                    'ignore-externals',
     672                )
     673            );
     674
     675            foreach ( Filesystem::list_files( "$tmp_dir/blueprints/", false /* non-recursive */, '!^blueprint[-\w]*\.json$!' ) as $plugin_blueprint ) {
     676                $filename = basename( $plugin_blueprint );
     677
     678                // Don't import oversize blueprints
     679                if ( filesize( $plugin_blueprint ) > $asset_limits['blueprint'] ) {
     680                    continue;
     681                }
     682
     683                // Make sure the blueprint file is valid json and contains the essentials; also minimize whitespace etc.
     684                $contents = self::normalize_blueprint_json( file_get_contents( $plugin_blueprint ), $plugin_slug );
     685                if ( !$contents ) {
     686                    continue;
     687                }
     688
     689                $assets['blueprint'][ $filename ] = array(
     690                    'filename'   => $filename,
     691                    'revision'   => $svn_export['revision'],
     692                    'resolution' => false,
     693                    'location'   => 'assets',
     694                    'locale'     => '',
     695                    'contents'   => $contents
     696                );
     697            }
     698
     699            // For the time being, limit the number of blueprints. Revise this when the case for multiple blueprints is more clear.
     700            if ( isset( $assets['blueprint'] ) && count ( $assets['blueprint'] ) > 10 ) {
     701                $assets['blueprint'] = array_slice( $assets['blueprint'], 0, 10, true );
    654702            }
    655703        }
     
    10411089        return array_unique( $build_files );
    10421090    }
     1091
     1092    static function normalize_blueprint_json( $blueprint_file_contents, $plugin_slug ) {
     1093        $decoded_file = json_decode( $blueprint_file_contents, true );
     1094
     1095        $contents = false;
     1096        if ( is_array( $decoded_file ) && JSON_ERROR_NONE === json_last_error() ) {
     1097
     1098            $has_self_install_step = false;
     1099            if ( isset( $decoded_file[ 'steps' ] ) ) {
     1100                foreach ( $decoded_file[ 'steps' ] as $i => $step ) {
     1101                    if ( 'installPlugin' === $step['step']
     1102                        && $plugin_slug === $step['pluginZipFile']['slug'] ) {
     1103                        $has_self_install_step = true;
     1104
     1105                        if ( true != $step['options']['activate'] ) {
     1106                            $decoded_file[ 'steps' ][ $i ][ 'options' ][ 'activate' ] = true;
     1107                        }
     1108                    }
     1109                }
     1110            }
     1111
     1112            if ( !$has_self_install_step ) {
     1113                $decoded_file['steps'][] = array(
     1114                    'step' => 'installPlugin',
     1115                    'pluginZipFile' => array(
     1116                        'resource' => 'wordpress.org/plugins',
     1117                        'slug'     => $plugin_slug,
     1118                    ),
     1119                    'options' => array(
     1120                        'activate' => true,
     1121                    )
     1122                );
     1123            }
     1124
     1125
     1126            $contents = json_encode( $decoded_file ); // Re-encode to minimize whitespace
     1127        }
     1128
     1129        return $contents;
     1130    }
    10431131}
Note: See TracChangeset for help on using the changeset viewer.