Making WordPress.org

Ticket #7251: 7251-add-opt-out-toggle.diff

File 7251-add-opt-out-toggle.diff, 8.0 KB (added by tellyworth, 16 months ago)

Add a button to the Advanced view allowing plugin committers to opt out of the Live Preview

  • plugins/plugin-directory/api/class-base.php

     
    3333                new Routes\Plugin_Support_Reps();
    3434                new Routes\Plugin_Self_Close();
    3535                new Routes\Plugin_Self_Transfer();
     36                new Routes\Plugin_Self_Toggle_Preview();
    3637                new Routes\Plugin_Release_Confirmation();
    3738                new Routes\Plugin_E2E_Callback();
    3839                new Routes\Plugin_Categorization();
  • plugins/plugin-directory/api/routes/class-plugin-self-toggle-preview.php

     
     1<?php
     2namespace WordPressdotorg\Plugin_Directory\API\Routes;
     3
     4use WordPressdotorg\Plugin_Directory\Plugin_Directory;
     5use WordPressdotorg\Plugin_Directory\Admin\Status_Transitions;
     6use WordPressdotorg\Plugin_Directory\API\Base;
     7use WordPressdotorg\Plugin_Directory\Tools;
     8
     9/**
     10 * An API endpoint for toggling Preview button availability on a particular plugin.
     11 *
     12 * @package WordPressdotorg_Plugin_Directory
     13 */
     14class Plugin_Self_Toggle_Preview extends Base {
     15
     16        public function __construct() {
     17                register_rest_route( 'plugins/v1', '/plugin/(?P<plugin_slug>[^/]+)/self-toggle-preview', [
     18                        'methods'             => \WP_REST_Server::CREATABLE,
     19                        'callback'            => [ $this, 'self_toggle_preview' ],
     20                        'args'                => [
     21                                'plugin_slug' => [
     22                                        'validate_callback' => [ $this, 'validate_plugin_slug_callback' ],
     23                                ],
     24                        ],
     25                        'permission_callback' => function( $request ) {
     26                                $plugin = Plugin_Directory::get_plugin_post( $request['plugin_slug'] );
     27
     28                                return current_user_can( 'plugin_self_close', $plugin );
     29                        },
     30                ] );
     31
     32                add_filter( 'rest_pre_echo_response', [ $this, 'override_cookie_expired_message' ], 10, 3 );
     33        }
     34
     35        /**
     36         * Redirect back to the plugins page when this endpoint is accessed with an invalid nonce.
     37         */
     38        function override_cookie_expired_message( $result, $obj, $request ) {
     39                if (
     40                        is_array( $result ) && isset( $result['code'] ) &&
     41                        preg_match( '!^/plugins/v1/plugin/([^/]+)/self-toggle-preview$!', $request->get_route(), $m )
     42                ) {
     43                        if ( 'rest_cookie_invalid_nonce' == $result['code'] ) {
     44                                wp_die( 'The link you have followed has expired.' );
     45                        } elseif ( 'rest_forbidden' == $result['code'] ) {
     46                                wp_die( "Sorry, You can't do that." );
     47                        }
     48                }
     49
     50                return $result;
     51        }
     52
     53        /**
     54         * Endpoint to toggle the Preview status.
     55         *
     56         * @param \WP_REST_Request $request The Rest API Request.
     57         * @return bool True if the favoriting was successful.
     58         */
     59        public function self_toggle_preview( $request ) {
     60                $plugin = Plugin_Directory::get_plugin_post( $request['plugin_slug'] );
     61                $result = [
     62                        'location' => wp_get_referer() ?: get_permalink( $plugin ),
     63                ];
     64                header( 'Location: ' . $result['location'] );
     65
     66                // Toggle the postmeta value. Note that there is a race condition here.
     67                $did = '';
     68                if ( get_post_meta( $plugin->ID, '_no_preview', true ) ) {
     69                        $r = delete_post_meta( $plugin->ID, '_no_preview' );
     70                        $did = 'enabled';
     71                } else {
     72                        $r = add_post_meta( $plugin->ID, '_no_preview', '1', true );
     73                        $did = 'disabled';
     74                }
     75
     76                // Add an audit-log entry as to why this has happened.
     77                Tools::audit_log(
     78                        sprintf( 'Plugin preview %s. Reason: Author Request from %s', $did, $_SERVER['REMOTE_ADDR'] ),
     79                        $plugin
     80                );
     81
     82                return $result;
     83        }
     84
     85}
  • plugins/plugin-directory/class-template.php

    Property changes on: plugins/plugin-directory/api/routes/class-plugin-self-toggle-preview.php
    ___________________________________________________________________
    Added: svn:eol-style
    ## -0,0 +1 ##
    +native
    \ No newline at end of property
     
    797797        }
    798798
    799799        /**
     800         * Generates a link to toggle the Live Preview button.
     801         *
     802         * @param int|\WP_Post|null $post Optional. Post ID or post object. Defaults to global $post.
     803         * @return string URL to toggle status.
     804         */
     805        public static function get_self_toggle_preview_link( $post = null ) {
     806                $post = get_post( $post );
     807
     808                return add_query_arg(
     809                        array( '_wpnonce' => wp_create_nonce( 'wp_rest' ) ),
     810                        home_url( 'wp-json/plugins/v1/plugin/' . $post->post_name . '/self-toggle-preview' )
     811                );
     812        }
     813
     814        /**
    800815         * Generates a link to enable Release Confirmations.
    801816         *
    802817         * @param int|\WP_Post|null $post Optional. Post ID or post object. Defaults to global $post.
  • themes/pub/wporg-plugins/inc/template-tags.php

     
    519519
    520520                // Output the self close button.
    521521                the_plugin_self_close_button();
     522
     523                // Output the toggle preview button.
     524                the_plugin_self_toggle_preview_button();
    522525        }
    523526
    524527}
     
    558561}
    559562
    560563/**
     564 * Displays a form for plugin committers to toggle the Live Preview button.
     565 */
     566function the_plugin_self_toggle_preview_button() {
     567        $post            = get_post();
     568        $toggle_link     = Template::get_self_toggle_preview_link( $post );
     569
     570        if ( ! current_user_can( 'plugin_self_close', $post ) ) {
     571                return;
     572        }
     573
     574        echo '<h4>' . esc_html__( 'Toggle Live Preview', 'wporg-plugins' ) . '</h4>';
     575        $preview_status = get_post_meta( $post->ID, '_no_preview', true ) ? 'disabled' : 'enabled';
     576        if ( 'enabled' === $preview_status ) {
     577                echo '<p>' . esc_html__( 'The Live Preview link to Playground is currently enabled. Use the toggle button to disable it.', 'wporg-plugins' ) . '</p>';
     578        } else {
     579                echo '<p>' . esc_html__( 'The Live Preview link to Playground is currently disabled. Use the toggle button to enable it.', 'wporg-plugins' ) . '</p>';
     580        }
     581
     582        echo '<div class="plugin-notice notice notice-warning notice-alt"><p>';
     583        _e( '<strong>Note:</strong> This only affects the availability of the Live Preview button on the plugin page. It does not prevent a plugin from running in the Playground.', 'wporg-plugins' );
     584        echo '</p></div>';
     585
     586        if ( $toggle_link ) {
     587                echo '<form method="POST" action="' . esc_url( $toggle_link ) . '" onsubmit="return confirm( jQuery(this).prev(\'.notice\').text() );">';
     588                // Translators: %s is the plugin name, as defined by the plugin itself.
     589                echo '<p><input class="button" type="submit" value="' . esc_attr( sprintf( __( 'Please toggle the Live Preview link for %s', 'wporg-plugins' ), get_the_title() ) ) . '" /></p>';
     590                echo '</form>';
     591        }
     592}
     593
     594/**
    561595 * Display a form to allow a plugin owner to transfer the ownership of a plugin to someone else.
    562596 * This does NOT remove their commit ability.
    563597 */
     
    671705                        wp_kses_post( $notice['html'] ) // Should have wrapping <p> tags.
    672706                );
    673707        }
    674 }
    675  No newline at end of file
     708}
  • themes/pub/wporg-plugins/template-parts/plugin-single.php

     
    4040
    4141                        <?php if ( 'publish' === get_post_status() || current_user_can( 'plugin_admin_view', $post ) ) : ?>
    4242                                <a class="plugin-download button download-button button-large" href="<?php echo esc_url( Template::download_link() ); ?>"><?php esc_html_e( 'Download', 'wporg-plugins' ); ?></a>
    43                                 <?php if ( !Template::is_plugin_outdated( $post ) ) : ?>
     43                                <?php if ( !Template::is_plugin_outdated( $post ) && !get_post_meta( $post->ID, '_no_preview', true ) ) : ?>
    4444                                        <a class="plugin-download button download-button button-large" href="<?php echo esc_url( Template::preview_link() ); ?>"><?php esc_html_e( 'Live Preview', 'wporg-plugins' ); ?></a>
    4545                                <?php endif; ?>
    4646                        <?php endif; ?>