Making WordPress.org


Ignore:
Timestamp:
08/17/2020 05:23:02 AM (4 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.