Making WordPress.org


Ignore:
Timestamp:
08/17/2020 05:23:02 AM (6 years ago)
Author:
tellyworth
Message:

Plugin dir: check for unique namespaces in the block checker.

This should permit block namespaces to be reused by the same author, but otherwise require that the namespace be unique.

See #5303.

File:
1 edited

Legend:

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

    r10172 r10173  
    77use WordPressdotorg\Plugin_Directory\Block_JSON\Parser as Block_JSON_Parser;
    88use WordPressdotorg\Plugin_Directory\Block_JSON\Validator as Block_JSON_Validator;
     9use WordPressdotorg\Plugin_Directory\Plugin_Directory;
    910
    1011/**
     
    9697                        }
    9798                }
     99        }
     100
     101        /**
     102         * Return the namespace part of a block name.
     103         *
     104         * @param string $block The block name.
     105         * @return string|bool The namespace, or false if the block name was invalid.
     106         */
     107        public function get_namespace( $block ) {
     108                $parts = explode( '/', $block, 2 );
     109                if ( 2 === count( $parts ) ) {
     110                        return $parts[0];
     111                }
     112                return false;
     113        }
     114
     115        /**
     116         * Return a list of contributors for a given plugin.
     117         *
     118         * @param WP_Post|int $post The post object or ID.
     119         */
     120        public function get_plugin_contributors( $post ) {
     121                $post = get_post( $post );
     122
     123                $contributors = get_terms( array(
     124                        'taxonomy'   => 'plugin_contributors',
     125                        'object_ids' => array( $post->ID ),
     126                        'orderby'    => 'term_order',
     127                        'fields'     => 'names',
     128                ) );
     129
     130                if ( is_wp_error( $contributors ) ) {
     131                        return array();
     132                }
     133
     134                return $contributors;
    98135        }
    99136
     
    357394
    358395                                while ( $last = array_pop( $context ) ) {
    359                                         if ( T_STRING === $last[0] && function_exists( $last[1] ) ) {
     396                                        if ( is_array( $last ) && T_STRING === $last[0] && function_exists( $last[1] ) ) {
    360397                                                $function_calls[] = array( $last[1], $last[2], $file );
    361398                                        }
     
    610647
    611648        /**
     649         * Namespace shouldn't clash with other plugins.
     650         */
     651        function check_for_unique_namespace() {
     652                $namespaces = array();
     653                foreach ( $this->blocks as $block ) {
     654                        if ( $parts = explode( '/', $block->name ) ) {
     655                                $namespaces[] = $parts[0] . '/';
     656                        }
     657                }
     658
     659                $namespaces = array_unique( $namespaces );
     660
     661                // Ignore known bogus namespaces
     662                $namespaces = array_diff( $namespaces, array( 'cgb/', 'create-block/', 'example/', 'block/', 'core/' ) );
     663
     664                if ( count( $namespaces ) > 0 ) {
     665                        foreach ( $namespaces as $namespace ) {
     666                                $meta_query[] = array(
     667                                        'key'      => 'block_name',
     668                                        'value'    => $namespace,
     669                                        'compare'  => 'LIKE',
     670                                );
     671                        }
     672                        if ( count( $meta_query ) > 1 ) {
     673                                $meta_query[ 'relation' ] = 'OR';
     674                        }
     675
     676                        $args = array(
     677                                'post_type' => 'plugin',
     678                                'post_status' => 'publish',
     679                                'nopaging' => true,
     680                                'meta_query' => $meta_query,
     681                        );
     682
     683                        $query = new \WP_Query( $args );
     684
     685                        foreach ( $query->posts as $post ) {
     686                                if ( $post->post_name === $this->slug ) {
     687                                        continue;
     688                                }
     689
     690                                $blocks = get_post_meta( $post->ID, 'block_name', false );
     691                                foreach ( $blocks as $block ) {
     692                                        if ( in_array( $this->get_namespace( $block ) . '/', $namespaces ) ) {
     693
     694                                                if ( $this->slug ) {
     695                                                        // We're testing a plugin that's in the directory already, so we can check to see if the other plugin shares some contributors.
     696
     697                                                        $this_plugin_contribs = $this->get_plugin_contributors( Plugin_Directory::get_plugin_post( $this->slug ) );
     698                                                        $other_plugin_contribs = $this->get_plugin_contributors( $post );
     699
     700                                                        if ( !array_intersect( $this_plugin_contribs, $other_plugin_contribs ) ) {
     701                                                                // If the other plugin has some contributors in common, it's probably fine to share a namespace.
     702                                                                // If not, it's an error that needs to be fixed.
     703                                                                $this->record_result(
     704                                                                        __FUNCTION__,
     705                                                                        'error',
     706                                                                        // translators: %1$s is the namespace, %2$s is a link to the plugin.
     707                                                                        sprintf( __( 'Please use a unique block namespace. Namespace %1$s is already used by %2$s.' ),
     708                                                                                '<code>' . $this->get_namespace( $block ) . '</code>',
     709                                                                                '<a href="' . esc_url( get_permalink( $post ) ) . '">' . esc_html( $post->post_title ) . '</a>'
     710                                                                        )
     711                                                                );
     712                                                        }
     713                                                } else {
     714                                                        // We're testing a plugin that's elsewhere (GitHub?) so we don't know its authors.
     715                                                        // If the namespace is used by another plugin we'll just warn about it, since that might be by the same author.
     716                                                        $this->record_result(
     717                                                                __FUNCTION__,
     718                                                                'warning',
     719                                                                // translators: %1$s is the namespace, %2$s is a link to the plugin.
     720                                                                sprintf( __( 'Please use a unique block namespace. Namespace %1$s is already used by %2$s.' ),
     721                                                                        '<code>' . $this->get_namespace( $block ) . '</code>',
     722                                                                        '<a href="' . esc_url( get_permalink( $post ) ) . '">' . esc_html( $post->post_title ) . '</a>'
     723                                                                )
     724                                                        );
     725                                                }
     726                                        }
     727                                }
     728                        }
     729
     730                }
     731
     732        }
     733
     734        /**
    612735         * There should be at least one block.
    613736         */
     
    688811                                        __( 'More than one top-level block was found: %s', 'wporg-plugins' ),
    689812                                        implode( ', ', $list )
    690                                 ),
    691                                 $block_name
     813                                )
    692814                        );
    693815                }
Note: See TracChangeset for help on using the changeset viewer.