Allow other modules to extend MenuItemsResource

Created on 17 March 2022, about 3 years ago
Updated 21 May 2024, 11 months ago

Currently the MenuItemsResource class is marked final. Meaning that no other PHP classes can extend this one.

Whilst I understand that no API is offered by this module, and it has not been built to be configurable in this way. Could we not say that the use of @internal is enough? And that we could allow other developers to extend the class at their own risk.

My scenario is:
I want to implement my own route that dynamically determines the menu based on some other context.
An easy way to do this is to define my own JSON:API resource, that extends MenuItemsResource, I then pass through the $menu to the parent and let it handle things from there. (I tried several different options, but the way the menu is determined means extending the class is the most convenient).

Feature request
Status

Closed: won't fix

Version

1.2

Component

Code

Created by

🇬🇧United Kingdom Leon Kessler

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Re-roll against latest 1.2.x

  • 🇬🇧United Kingdom Eli-T Manchester

    Looks like #3270141-5: Allow other modules to extend MenuItemsResource isn't quite enough to successfully subclass MenuItemsResource in 1.2.5.

    In our case, this broke because in 1.2.5, MenuItemsResource now implements ContainerInjectionInterface.

    When \Drupal\jsonapi_resources\Unstable\Controller\JsonapiResourceController::processRequest() is handling a request for the subclassed resource, it calls $this->getJsonapiResource(), which ultimately uses \Drupal\Core\DependencyInjection\ClassResolver::getInstanceFromDefinition() to get the class.

    This part of that function now has different behaviour

      if (is_subclass_of($definition, 'Drupal\Core\DependencyInjection\ContainerInjectionInterface')) {
        $instance = $definition::create($this->container);
      }
      else {
        $instance = new $definition();
      }
    

    because in 1.2.5 we pass the if condition, unlike 1.2.4.

    And because \Drupal\jsonapi_menu_items\Resource\MenuItemsResource::create() returns new self(), even when $definition is set to our subclass, the parent class is returned.

    Therefore jsonapi_resources acts as if the parent class was requested rather than the subclass.

    Here is an addition to the patch in #3270141-5: Allow other modules to extend MenuItemsResource that changes self to static. I presume this will annoy PHPStan. However, this makes inheritance possible here and works with our use case. I'd be grateful to hear of any better approaches though!

  • Pipeline finished with Failed
    11 months ago
    Total: 240s
    #173608
  • 🇬🇧United Kingdom Eli-T Manchester

    On a tangential note, whilst diffing 1.2.4 and 1.2.5 to try to figure out what had changed, it felt more like this could have been a minor release than a patch release!

  • Status changed to Closed: won't fix 11 months ago
  • 🇬🇧United Kingdom Eli-T Manchester

    Closing this issue now as we have refactored our custom module to decorate MenuItemsResource rather than extend it. This works with no changes to this module. Note you need to implement getRouteResourceTypes() on the decorator class, and in response call it on the decorated class if you do this.

Production build 0.71.5 2024