Skip to content

isClassExtendedWith doesnt work in Controller::extend #1460

Description

@quendistudio

Winter CMS Build

1.2.9 and 1.2.11

PHP Version

8.3

Database engine

MySQL/MariaDB

Plugins installed

No response

Issue description

It is not possible to use isClassExtendedWith when extending a controller. This example from the documentation https://wintercms.com/docs/v1.2/docs/services/behaviors#extending-a-clas generates an Exception if the controller is already extended using the same behavior:

UsersController::extend(function ($controller) {
    // Implement behavior if not already implemented
    if (!$controller->isClassExtendedWith(\Backend\Behaviors\RelationController::class)) {
        $controller->implement[] = \Backend\Behaviors\RelationController::class;
    }

    // Define property if not already defined
    if (!isset($controller->relationConfig)) {
        $controller->addDynamicProperty('relationConfig');
    }

    // Splice in configuration safely
    $myConfigPath = '$/myvendor/myplugin/controllers/users/config_relation.yaml';

    $controller->relationConfig = $controller->mergeConfig(
        $controller->relationConfig,
        $myConfigPath
    );
}

Exception

Class Backend\Controllers\Users has already been extended with Backend\Behaviors\RelationController

With ExtendableTrait::extendableConstruct() the order seems to be:

  1. First: all extend() callbacks are run (including yours).
  2. Then: the behaviors listed in $implement are applied (including RelationController).

And isClassExtendedWith() returns true only when the behavior has already been applied (i.e. when it is present in extensionData['extensions']).

Steps to replicate

When UsersController already implement \Backend\Behaviors\RelationController::class, try this in boot() on your Plugin.php:

UsersController::extend(function ($controller) {
    // Implement behavior if not already implemented
    if (!$controller->isClassExtendedWith(\Backend\Behaviors\RelationController::class)) {
        $controller->implement[] = \Backend\Behaviors\RelationController::class;
    }
}

You can try with other controllers and other behaviors, like \Backend\Behaviors\FormController::class or \Backend\Behaviors\ListController::class for example. Same issue.

Workaround

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions