Making WordPress.org

Changeset 13076


Ignore:
Timestamp:
12/21/2023 05:40:09 AM (2 years ago)
Author:
tellyworth
Message:

Plugin Dir: Add Preview links for moderators in plugin queue

This adds private Playground Preview links for the plugin review team to more easily test newly submitted plugins that have not yet been published.

Plugins are loaded with plugin-check active.

See #7380.

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

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/list-table/class-plugin-posts.php

    r13034 r13076  
    712712
    713713            printf(
    714                 '<a href="%1$s">%2$s</a><br>%3$s</li>',
     714                '<a href="%1$s">%2$s</a><br>%3$s<br>(<a href="%4$s" target="_blank">preview</a>)</li>',
    715715                esc_url( $url ),
    716716                esc_html( $name ),
    717                 esc_html( $zip_size )
     717                esc_html( $zip_size ),
     718                esc_url( Template::preview_link_zip( $post->post_name, $zip_file->ID ) )
    718719            );
    719720        }
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/metabox/class-review-tools.php

    r12862 r13076  
    128128                list( $zip_url, $zip_file ) = $zip;
    129129                $zip_size                   = size_format( filesize( get_attached_file( $zip_file->ID ) ), 1 );
     130                $zip_preview                = Template::preview_link_zip( $slug, $zip_file->ID );
    130131
    131132                printf(
    132                     '<li>%1$s <a href="%2$s">%3$s</a> (%4$s)</li>',
     133                    '<li>%1$s <a href="%2$s">%3$s</a> (%4$s) (<a href="%5$s" target="_blank">preview</a>)</li>',
    133134                    esc_html( $zip_date ),
    134135                    esc_url( $zip_url ),
    135136                    esc_html( basename( $zip_url ) ),
    136                     esc_html( $zip_size )
     137                    esc_html( $zip_size ),
     138                    esc_url( $zip_preview )
    137139                );
    138140            }
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/api/routes/class-plugin-blueprint.php

    r13019 r13076  
    1818            'methods'             => array( \WP_REST_Server::READABLE, \WP_REST_Server::CREATABLE ),
    1919            'callback'            => array( $this, 'blueprint' ),
     20            // Note: the zip part of the endpoint is also public, since playground requests blueprints without cookie credentials
    2021            'permission_callback' => '__return_true',
    2122            'args'                => array(
     
    3536    public function blueprint( $request ) {
    3637        $plugin = Plugin_Directory::get_plugin_post( $request['plugin_slug'] );
     38
     39        // Direct zip preview for plugin reviewers
     40        if ( $request->get_param('zip_hash') ) {
     41            foreach ( get_attached_media( 'application/zip', $plugin ) as $zip_file ) {
     42                if ( hash_equals( Template::preview_link_hash( $zip_file->ID, 0 ), $request->get_param('zip_hash') ) ||
     43                     hash_equals( Template::preview_link_hash( $zip_file->ID, -1 ), $request->get_param('zip_hash') ) ) {
     44                    $zip_url = wp_get_attachment_url( $zip_file->ID );
     45                    $zip_blueprint =<<<EOF
     46{
     47    "landingPage": "/wp-admin/plugins.php",
     48    "preferredVersions": {
     49        "php": "8.0",
     50        "wp": "latest"
     51    },
     52    "phpExtensionBundles": [
     53        "kitchen-sink"
     54    ],
     55    "features": {
     56        "networking": true
     57    },
     58    "steps": [
     59        {
     60            "step": "installPlugin",
     61            "pluginZipFile": {
     62                "resource": "wordpress.org/plugins",
     63                "slug": "plugin-check"
     64            }
     65        },
     66        {
     67            "step": "installPlugin",
     68            "pluginZipFile": {
     69                "resource": "url",
     70                "url": "$zip_url"
     71            }
     72        },
     73        {
     74            "step": "login",
     75            "username": "admin",
     76            "password": "password"
     77        }
     78    ]
     79}
     80EOF;
     81                    header( 'Access-Control-Allow-Origin: https://playground.wordpress.net' );
     82                    die( $zip_blueprint );
     83                }
     84            }
     85        }
    3786
    3887        $blueprints = get_post_meta( $plugin->ID, 'assets_blueprints', true );
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/class-template.php

    r13061 r13076  
    763763
    764764        return sprintf( 'https://playground.wordpress.net/?plugin=%s&blueprint-url=%s', esc_attr($post->post_name), esc_attr($blueprint['url'] ) );
     765    }
     766
     767    /**
     768     * Generate a live preview (playground) link for a zip attachment. Needed for newly uploaded plugins that have not yet been published.
     769     *
     770     * @param string $slug            The slug of the plugin post.
     771     * @param int $attachment_id      The ID of the attachment post corresponding to a plugin zip file. Must be attached to the post identified by $slug.
     772     * @return false|string           The preview URL.
     773     */
     774    public static function preview_link_zip( $slug, $attachment_id ) {
     775
     776        $zip_hash = self::preview_link_hash( $attachment_id );
     777        if ( !$zip_hash ) {
     778            return false;
     779        }
     780        $zip_blueprint = sprintf( 'https://wordpress.org/plugins/wp-json/plugins/v1/plugin/%s/blueprint.json?zip_hash=%s', esc_attr( $slug ), esc_attr( $zip_hash ) );
     781        $zip_preview = add_query_arg( 'blueprint-url', urlencode($zip_blueprint), 'https://playground.wordpress.net/' );
     782
     783        return $zip_preview;
     784    }
     785
     786    /**
     787     * Return a time-dependent variable for zip preview links.
     788     *
     789     * @param int $lifespan           The life span of the nonce, in seconds. Default is one week.
     790     * @return float                  The tick value.
     791     */
     792    public static function preview_link_tick( $lifespan = WEEK_IN_SECONDS ) {
     793        return ceil( time() / ( $lifespan / 2 ) );
     794    }
     795
     796    /**
     797     * Return a nonce-style hash for zip preview links.
     798     *
     799     * @param int $attachment_id      The ID of the attachment post corresponding to a plugin zip file.
     800     * @param int $tick_offest        Number to subtract from the nonce tick. Use both 0 and -1 to verify older nonces.
     801     * @return false|string           The hash as a hex string; or false if the attachment ID is invalid.
     802     */
     803    public static function preview_link_hash( $attachment_id, $tick_offset = 0 ) {
     804        $file = get_attached_file( $attachment_id );
     805        if ( !$file ) {
     806            return false;
     807        }
     808        $tick = self::preview_link_tick() - $tick_offset;
     809        return wp_hash( $tick . '|' . $file, 'nonce' );
    765810    }
    766811
Note: See TracChangeset for help on using the changeset viewer.