Making WordPress.org

Changeset 4261


Ignore:
Timestamp:
10/19/2016 03:27:01 AM (8 years ago)
Author:
dd32
Message:

Plugin Directory: Readme Validator: Strip out the wp-admin handling in the readme handler and streamline the error checks a little.

See #2128

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/readme/class-validator.php

    r4259 r4261  
    2222
    2323    /**
    24      * Validator constructor.
     24     * Validates a readme by URL.
     25     *
     26     * @param string $url The URL of the readme to validate.
     27     * @return array Array of the readme validation results.
    2528     */
    26     private function __construct() {
    27         add_action( 'plugin_page_readme_validator', array( $this, 'add_form_fields' ) );
    28         add_action( 'plugin_page_readme_validator', array( $this, 'validate' ) );
     29    public function validate_url( $url ) {
     30        $url = esc_url_raw( $url );
     31
     32        if ( strtolower( substr( $url, -10 ) ) != 'readme.txt' ) {
     33            /* Translators: File name; */
     34            $error = sprintf( __( 'URL must end in %s!', 'wporg-plugins' ), '<code>readme.txt</code>' );
     35            return array(
     36                'errors' => array( $error )
     37            );
     38        }
     39
     40        $readme = wp_safe_remote_get( $url );
     41        if ( ! $readme_text = wp_remote_retrieve_body( $readme ) ) {
     42            $error = __( 'Invalid readme.txt URL.', 'wporg-plugins' );
     43            return array(
     44                'errors' => array( $error )
     45            );
     46        }
     47
     48        return $this->validate_content( $readme_text );
    2949    }
    3050
    3151    /**
    32      * Displays a for to validate readme.txt files and blobs of text.
    33      */
    34     public function display() {
    35         ?>
    36         <div class="wrap">
    37             <h2><?php _e( 'WordPress Plugin readme.txt Validator', 'wporg-plugins' ); ?></h2>
    38             <?php settings_errors( 'wporg-plugins-readme' ); ?>
    39             <form method="post" action="<?php echo esc_url( add_query_arg( array( 'post_type' => 'plugin', 'page' => 'readme_validator' ), admin_url( 'edit.php' ) ) ); ?>">
    40                 <?php
    41                 wp_nonce_field( 'validate-readme' );
    42                 do_settings_sections( 'readme_validator' );
    43                 submit_button( __( 'Validate', 'wporg-plugins' ) );
    44                 ?>
    45             </form>
    46         </div>
    47         <?php
    48     }
    49 
    50     /**
    51      * Registers form fields for this admin page.
    52      */
    53     public function add_form_fields() {
    54         add_settings_section( 'default', '', array( $this, 'section_description' ), 'readme_validator' );
    55 
    56         add_settings_field( 'readme_url', __( 'URL to readme.txt file', 'wporg-plugins' ), array( $this, 'url_input' ), 'readme_validator', 'default', array(
    57             'label_for' => 'readme_url',
    58         ) );
    59         add_settings_field( 'readme_text', __( 'Text of readme.txt', 'wporg-plugins' ), array( $this, 'textarea' ),  'readme_validator', 'default', array(
    60             'label_for' => 'readme_contents',
    61         ) );
    62     }
    63 
    64     /**
    65      * Validates readme.txt contents and adds feedback.
    66      */
    67     public function validate() {
    68         if ( ! isset( $_REQUEST['_wpnonce'] ) ) {
    69             return;
    70         }
    71         check_admin_referer( 'validate-readme' );
    72 
    73         $readme    = '';
    74 
    75         if ( ! empty( $_REQUEST['readme_url'] ) ) {
    76             $url = esc_url_raw( $_REQUEST['readme_url'] );
    77 
    78             if ( strtolower( substr( $url, -10 ) ) != 'readme.txt' ) {
    79                 /* Translators: File name; */
    80                 add_settings_error( 'wporg-plugins-readme', 'readme-validator', sprintf( __( 'URL must end in %s!', 'wporg-plugins' ), '<code>readme.txt</code>' ) );
    81                 return;
    82             }
    83 
    84             if ( ! $readme = @file_get_contents( $url ) ) {
    85                 add_settings_error( 'wporg-plugins-readme', 'readme-validator', __( 'Invalid readme.txt URL.', 'wporg-plugins' ) );
    86                 return;
    87             }
    88 
    89         } elseif ( ! empty( $_REQUEST['readme_contents'] ) && is_string( $_REQUEST['readme_contents'] ) ) {
    90             $readme = wp_unslash( $_REQUEST['readme_contents'] );
    91         }
    92 
    93         if ( empty( $readme ) ) {
    94             return;
    95         }
    96 
    97         return $this->validate_content( $readme );
    98     }
    99 
    100     /**
    101      * Validates content via a string paramater and adds feedback.
     52     * Validates readme contents by string.
     53     *
     54     * @param string $readme The text of the readme.
     55     * @return array Array of the readme validation results.
    10256     */
    10357    public function validate_content( $readme ) {
    10458
    105         $temp_file = Filesystem::temp_directory() . '/readme.txt';
    106         $errors    = array();
    107         $warnings  = array();
    108         $notes     = array();
     59        $readme = new Parser( 'data:text/plain,' . urlencode( $readme ) );
    10960
    110         file_put_contents( $temp_file, $readme );
    111         $readme = new Parser( $temp_file );
     61        $errors = $warnings = $notes = array();
    11262
    11363        // Fatal errors.
    11464        if ( empty( $readme->name ) ) {
    11565            /* Translators: Plugin header tag; */
    116             add_settings_error( 'wporg-plugins-readme', 'readme-validator', sprintf( __( "Fatal Error:\nNo plugin name detected. Plugin names look like: %s", 'wporg-plugins' ), '<code>=== Plugin Name ===</code>' ) );
    117             $errors[] = array( 'error', sprintf( __( "Fatal Error:\nNo plugin name detected.    Plugin names look like: %s", 'wporg-plugins' ), '<code>=== Plugin Name ===</code>' ) );
    118             return $errors;
     66            $errors[] = sprintf( __( "No plugin name detected. Plugin names look like: %s", 'wporg-plugins' ), '<code>=== Plugin Name ===</code>' );
    11967        }
    12068
     
    13583            /* Translators: Plugin header tag; */
    13684            $warnings[] = sprintf( __( 'No %s listed.', 'wporg-plugins' ), '<code>Contributors</code>' );
    137         }
    138 
    139         if ( $warnings ) {
    140             $message = __( 'Warnings:', 'wporg-plugins' ) . "\n<ul class='warning error'>\n";
    141             foreach ( $warnings as $warning ) {
    142                 $message .= "<li>$warning</li>\n";
    143             }
    144             $message .= "</ul>\n</div>";
    145 
    146             if ( function_exists( 'add_settings_error' ) ) {
    147                 add_settings_error( 'wporg-plugins-readme', 'readme-validator', $message, 'notice-warning' );
    148             }
    149             return $message;
    15085        }
    15186
     
    171106        }
    172107
    173         if ( $notes ) {
    174             $message = __( 'Notes:' ) . "\n<ul class='note error'>\n";
    175             foreach ( $notes as $note ) {
    176                 $message .= "<li>$note</li>\n";
    177             }
    178             $message .= "</ul>\n</div>";
     108        return compact( 'errors', 'warnings', 'notes' );
    179109
    180             if ( function_exists( 'add_settings_error' ) ) {
    181                 add_settings_error( 'wporg-plugins-readme', 'readme-validator', $message, 'notice-info' );
    182             }
    183             return $message;
    184         }
    185 
    186         /* Translators: File name; */
    187         if ( function_exists( 'add_settings_error' ) ) {
    188             add_settings_error( 'wporg-plugins-readme', 'readme-validator', sprintf( __( 'Your %s rocks.  Seriously.  Flying colors.', 'wporg-plugins' ), '<code>readme.txt</code>' ), 'updated' );
    189         }
    190110    }
    191111
    192 
    193     /**
    194      * Help text for the form following after it.
    195      */
    196     public function section_description() {
    197         /* Translators: File name; */
    198         echo '<p>' . sprintf( __( 'Enter the URL to your %s file or paste its content below.' ), '<code>readme.txt</code>' ) . '</p>';
    199     }
    200 
    201     /**
    202      * Displays an input field for the readme.txt URL.
    203      */
    204     public function url_input() {
    205         $url = empty( $_REQUEST['readme_url'] ) ? '' : $_REQUEST['readme_url'];
    206         ?>
    207         <label>
    208             <input type="url" id="readme_url" name="readme_url" size="70" value="<?php echo esc_url( $url ); ?>" />
    209         </label>
    210         <?php
    211     }
    212 
    213     /**
    214      * Displays a textarea for readme.txt blobs.
    215      */
    216     public function textarea() {
    217         $text = empty( $_REQUEST['readme_contents'] ) ? '' : wp_unslash( $_REQUEST['readme_contents'] );
    218         ?>
    219         <label>
    220             <textarea type="text" id="readme_contents" class="large-text" name="readme_contents" cols="50" rows="10"><?php echo esc_textarea( $text ); ?></textarea>
    221         </label>
    222         <?php
    223     }
    224112}
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/shortcodes/class-readme-validator.php

    r4259 r4261  
    55class Readme_Validator {
    66
    7     private $errors = array();
    8 
    9     /**
    10      * Fetch the instance of the Readme_Validator class.
    11      *
    12      * @static
    13      */
    14     public static function instance() {
    15         static $instance = null;
    16 
    17         return ! is_null( $instance ) ? $instance : $instance = new Readme_Validator();
    18     }
    19 
    20     private function __construct() {
    21     }
    22 
    23     private function display_errors( $errors ) {
    24         if ( is_array( $errors ) && !empty( $errors ) ) {
    25             $message = __( 'Warnings:', 'wporg-plugins' ) . "\n<ul class='warning error'>\n";
    26             foreach ( $errors as $error ) {
    27                 $message .= "<li>" . esc_html($error) . "</li>\n";
    28             }
    29             $message .= "</ul>\n</div>";
    30 
    31             echo $message;
    32         }
    33 
    34     }
    35 
    367    /**
    378     * Displays a form to validate readme.txt files and blobs of text.
    389     */
    39     public function display() {
    40 
    41         $message = null;
    42         if ( !empty( $_POST ) ) {
    43             $message = self::validate();
    44         }
    45 
     10    public static function display() {
    4611        ?>
    4712        <div class="wrap">
    4813            <h2><?php _e( 'WordPress Plugin readme.txt Validator', 'wporg-plugins' ); ?></h2>
    49             <?php if ( $message ) echo $message; ?>
    50             <form method="post" action="<?php echo esc_url( add_query_arg( array() ) ); ?>">
    51                 <input type="hidden" name="url" value="1" />
    52                 <p>http://<input type="text" name="readme_url" size="70" /> <input type="submit" value="Validate!" /></p>
    53                 <?php
    54                 wp_nonce_field( 'validate-readme-url' );
    55                 ?>
     14
     15            <?php
     16            if ( $_POST ) {
     17                self::validate_readme();
     18            }
     19            ?>
     20
     21            <form method="post" action="">
     22                <p>
     23                    <input type="text" name="readme_url" size="70" placeholder="https://" value="<?php if ( isset( $_GET['readme_url'] ) ) { echo esc_attr( $_POST['readme_url'] ); } ?>" />
     24                    <input type="submit" value="<?php esc_attr_e( 'Validate!', 'wporg-plugins' ); ?>" />
     25                </p>
    5626            </form>
     27
    5728            <p><?php _e( '... or paste your <code>readme.txt</code> here:', 'wporg-plugins' ); ?></p>
    58             <form method="post" action="<?php echo esc_url( add_query_arg( array() ) ); ?>">
    59                 <input type="hidden" name="text" value="1" />
    60                 <textarea rows="20" cols="100" name="readme_contents"></textarea>
    61                 <p><input type="submit" value="Validate!" /></p>
    62                 <?php
    63                 wp_nonce_field( 'validate-readme-text' );
    64                 ?>
     29            <form method="post" action="">
     30                <textarea rows="20" cols="100" name="readme_contents" placeholder="=== Plugin Name ==="><?php
     31                    if ( isset( $_POST['readme_contents'] ) ) {
     32                        echo esc_textarea( wp_unslash( $_POST['readme_contents'] ) );
     33                    }
     34                ?></textarea>
     35                <p><input type="submit" value="<?php esc_attr_e( 'Validate!', 'wporg-plugins' ); ?>" /></p>
    6536            </form>
    6637        </div>
     
    7142     * Validates readme.txt contents and adds feedback.
    7243     */
    73     public function validate() {
     44    protected static function validate_readme() {
     45        if (  !empty( $_POST['readme_url'] ) ) {
     46            $errors = Validator::instance()->validate_url( wp_unslash( $_POST['readme_url'] ) );
    7447
    75         $readme    = '';
     48        } elseif ( !empty( $_POST['readme_contents'] ) ) {
     49            $errors = Validator::instance()->validate_content( wp_unslash( $_REQUEST['readme_contents'] ) );
    7650
    77         if ( !empty( $_POST['url'] )
    78             && !empty( $_POST['readme_url'] )
    79             && !empty( $_POST['_wpnonce'] )
    80             && wp_verify_nonce( $_POST['_wpnonce'], 'validate-readme-url' ) ) {
    81                 $url = esc_url_raw( $_POST['readme_url'] );
    82 
    83                 if ( strtolower( substr( $url, -10 ) ) != 'readme.txt' ) {
    84                     /* Translators: File name; */
    85                     self::instance()->errors[] = sprintf( __( 'URL must end in %s!', 'wporg-plugins' ), '<code>readme.txt</code>' );
    86                     return;
    87                 }
    88 
    89                 if ( ! $readme = @file_get_contents( $url ) ) {
    90                     self::instance()->errors[] = __( 'Invalid readme.txt URL.', 'wporg-plugins' );
    91                     return;
    92                 }
    93             }
    94         elseif ( !empty( $_POST['text'] )
    95             && !empty( $_POST['readme_contents'] )
    96             && !empty( $_POST['_wpnonce'] )
    97             && wp_verify_nonce( $_POST['_wpnonce'], 'validate-readme-text' ) ) {
    98                 $readme = wp_unslash( $_REQUEST['readme_contents'] );
    99             }
    100 
    101         if ( empty( $readme ) ) {
     51        } else {
    10252            return;
    10353        }
    10454
    105         return Validator::instance()->validate_content( $readme );
    106 
     55        $error_types = array(
     56            'errors'   => __( 'Fatal Errors:', 'wporg-plugins' ),
     57            'warnings' => __( 'Warnings:', 'wporg-plugins' ),
     58            'notes'    => __( 'Notes:', 'wporg-plugins' )
     59        );
     60        foreach ( $error_types as $field => $warning_label ) {
     61            if ( !empty( $errors[ $field ] ) ) {
     62                echo "{$warning_label}\n<ul class='{$field} error'>\n";
     63                foreach ( $errors[ $field ] as $notice ) {
     64                    echo "<li>{$notice}</li>\n";
     65                }
     66                echo "</ul>\n";
     67            }
     68        }
    10769    }
    10870}
Note: See TracChangeset for help on using the changeset viewer.