Make WordPress Core

Changeset 62309 for branches/7.0


Ignore:
Timestamp:
05/06/2026 07:56:41 PM (3 months ago)
Author:
desrosj
Message:

Connectors: Add is_active callback support to plugin registration.

Adds an optional is_active callable to the plugin definition accepted by WP_Connector_Registry::register(). The callback receives no arguments, must return a boolean, and is used by the Connectors screen to decide whether a connector's backing plugin is currently active. When omitted, it defaults to __return_true; when provided but not callable, registration fails with a _doing_it_wrong() notice.

Developed in: https://github.com/WordPress/wordpress-develop/pull/11565

Reviewed by desrosj.
Merges [62288] to the 7.0 branch.

Props iamadisingh, jorgefilipecosta, mukesh27, gziolo, desrosj.
Fixes #65020.

Location:
branches/7.0
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/7.0

  • branches/7.0/src/wp-includes/class-wp-connector-registry.php

    r62308 r62309  
    4141 *     },
    4242 *     plugin?: array{
    43  *         file: non-empty-string
     43 *         file: non-empty-string,
     44 *         is_active?: callable(): bool
    4445 *     }
    4546 * }
     
    110111         *         Optional. Plugin data for install/activate UI.
    111112         *
    112          *         @type string $file The plugin's main file path relative to the plugins
    113          *                            directory (e.g. 'my-plugin/my-plugin.php' or 'hello.php').
     113         *         @type string   $file      Optional. The plugin's main file path relative to the
     114         *                                   plugins directory (e.g. 'my-plugin/my-plugin.php' or
     115         *                                   'hello.php').
     116         *         @type callable $is_active Optional callback to determine whether the plugin
     117         *                                   is active. Receives no arguments and must return bool.
     118         *                                   Defaults to `__return_true`.
    114119         *     }
    115120         * }
     
    244249                }
    245250
    246                 if ( ! empty( $args['plugin'] ) && is_array( $args['plugin'] ) && ! empty( $args['plugin']['file'] ) ) {
    247                         $connector['plugin'] = array( 'file' => $args['plugin']['file'] );
     251                $connector['plugin'] = array();
     252
     253                if ( ! empty( $args['plugin'] ) && is_array( $args['plugin'] ) ) {
     254                        if ( ! empty( $args['plugin']['file'] ) ) {
     255                                $connector['plugin']['file'] = $args['plugin']['file'];
     256                        }
     257
     258                        if ( isset( $args['plugin']['is_active'] ) ) {
     259                                if ( ! is_callable( $args['plugin']['is_active'] ) ) {
     260                                        _doing_it_wrong(
     261                                                __METHOD__,
     262                                                /* translators: %s: Connector ID. */
     263                                                sprintf( __( 'Connector "%s" plugin is_active must be callable.' ), esc_html( $id ) ),
     264                                                '7.0.0'
     265                                        );
     266                                        return null;
     267                                }
     268
     269                                $connector['plugin']['is_active'] = $args['plugin']['is_active'];
     270                        }
     271                }
     272
     273                if ( ! isset( $connector['plugin']['is_active'] ) ) {
     274                        $connector['plugin']['is_active'] = '__return_true';
    248275                }
    249276
  • branches/7.0/src/wp-includes/connectors.php

    r62308 r62309  
    368368                        }
    369369                }
     370
     371                if ( ! isset( $args['plugin']['is_active'] ) ) {
     372                        $args['plugin']['is_active'] = static function () use ( $ai_registry, $id ): bool {
     373                                try {
     374                                        return $ai_registry->hasProvider( $id );
     375                                } catch ( Exception $e ) {
     376                                        return false;
     377                                }
     378                        };
     379                }
     380
    370381                $registry->register( $id, $args );
    371382        }
     
    641652        $registry = AiClient::defaultRegistry();
    642653
    643         if ( ! function_exists( 'is_plugin_active' ) ) {
    644                 require_once ABSPATH . 'wp-admin/includes/plugin.php';
    645         }
    646 
    647654        $connectors = array();
    648655        foreach ( wp_get_connectors() as $connector_id => $connector_data ) {
     
    677684                if ( ! empty( $connector_data['plugin']['file'] ) ) {
    678685                        $file         = $connector_data['plugin']['file'];
    679                         $is_installed = file_exists( wp_normalize_path( WP_PLUGIN_DIR . '/' . $file ) );
    680                         $is_activated = $is_installed && is_plugin_active( $file );
     686                        $is_activated = (bool) call_user_func( $connector_data['plugin']['is_active'] );
     687                        $is_installed = $is_activated || file_exists( wp_normalize_path( WP_PLUGIN_DIR . '/' . $file ) );
    681688
    682689                        $connector_out['plugin'] = array(
  • branches/7.0/tests/phpunit/tests/connectors/wpConnectorRegistry.php

    r62195 r62309  
    300300
    301301                $this->assertArrayHasKey( 'plugin', $result );
    302                 $this->assertSame( array( 'file' => 'my-plugin/my-plugin.php' ), $result['plugin'] );
    303         }
    304 
    305         /**
    306          * @ticket 64791
    307          */
    308         public function test_register_omits_plugin_when_not_provided() {
     302                $this->assertSame( 'my-plugin/my-plugin.php', $result['plugin']['file'] );
     303        }
     304
     305        /**
     306         * @ticket 65020
     307         */
     308        public function test_register_stores_plugin_is_active_callback() {
     309                $args           = self::$default_args;
     310                $args['plugin'] = array(
     311                        'file'      => 'my-plugin/my-plugin.php',
     312                        'is_active' => '__return_true',
     313                );
     314
     315                $result = $this->registry->register( 'with-callback', $args );
     316
     317                $this->assertIsArray( $result );
     318                $this->assertArrayHasKey( 'is_active', $result['plugin'] );
     319                $this->assertIsCallable( $result['plugin']['is_active'] );
     320        }
     321
     322        /**
     323         * @ticket 65020
     324         */
     325        public function test_register_rejects_non_callable_plugin_is_active() {
     326                $this->setExpectedIncorrectUsage( 'WP_Connector_Registry::register' );
     327
     328                $args           = self::$default_args;
     329                $args['plugin'] = array(
     330                        'file'      => 'my-plugin/my-plugin.php',
     331                        'is_active' => 'not_a_real_function_name',
     332                );
     333
     334                $result = $this->registry->register( 'bad-callback', $args );
     335
     336                $this->assertNull( $result );
     337        }
     338
     339        /**
     340         * @ticket 65020
     341         */
     342        public function test_register_defaults_plugin_is_active_to_return_true() {
     343                $args           = self::$default_args;
     344                $args['plugin'] = array( 'file' => 'my-plugin/my-plugin.php' );
     345
     346                $result = $this->registry->register( 'default-callback', $args );
     347
     348                $this->assertIsArray( $result );
     349                $this->assertArrayHasKey( 'is_active', $result['plugin'] );
     350                $this->assertSame( '__return_true', $result['plugin']['is_active'] );
     351        }
     352
     353        /**
     354         * @ticket 64791
     355         */
     356        public function test_register_defaults_plugin_when_not_provided() {
    309357                $result = $this->registry->register( 'no-plugin', self::$default_args );
    310358
    311                 $this->assertArrayNotHasKey( 'plugin', $result );
     359                $this->assertArrayHasKey( 'plugin', $result );
     360                $this->assertArrayNotHasKey( 'file', $result['plugin'] );
     361                $this->assertSame( '__return_true', $result['plugin']['is_active'] );
    312362        }
    313363
Note: See TracChangeset for help on using the changeset viewer.