Problem/Motivation

Drupal\dropzonejs\Controller\UploadController still wires its dependencies by hand through create() and a matching __construct(). Since Drupal 10.3, controllers can pull their services straight from type-hinted constructor arguments via Drupal\Core\DependencyInjection\AutowireTrait, which removes the boilerplate create() method entirely (change record #3395716).

There is one wrinkle: the controller currently injects the request object directly:

public static function create(ContainerInterface $container) {
    return new static(
      $container->get('dropzonejs.upload_handler'),
      $container->get('request_stack')->getCurrentRequest()
    );
}

AutowireTrait can only autowire actual services, and Symfony\Component\HttpFoundation\Request is not one — it is a request-scoped object produced by the request_stack service. Injecting the current Request into a service/controller is also discouraged, because the instance is captured at construction time and can go stale on sub-requests. So this cleanup should switch to injecting the request_stack service and calling getCurrentRequest() at the point of use.

Proposed resolution

- Add use Drupal\Core\DependencyInjection\AutowireTrait; and use AutowireTrait; in UploadController, and remove the manual create() method.
- Replace the injected Request with the request_stack service (Symfony\Component\HttpFoundation\RequestStack), type-hinted on the constructor so it autowires, and update handleUploads() to read the file from $this->requestStack->getCurrentRequest()->files->get('file').
- Use constructor property promotion, matching the style adopted in the OOP hook classes from #3576977.

Issue fork dropzonejs-3613233

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

velmir_taky created an issue. See original summary.

velmir_taky’s picture

Status: Active » Needs review

Pushed a fix. The first pass broke the actual upload route — AutowireTrait::create() couldn't resolve UploadHandlerInterface because the service was only registered by id, so the controller 500'd and the functional upload tests errored.

Added the autowiring alias in dropzonejs.services.yml, and reworked the kernel test to build the controller through the container (::create()) instead of new, so the DI wiring is actually covered now — it goes red without the alias and green with it.

csakiistvan’s picture

Assigned: Unassigned » csakiistvan
csakiistvan’s picture

Assigned: csakiistvan » Unassigned
Status: Needs review » Reviewed & tested by the community

Environment

  • Drupal: 11.4.4
  • PHP: 8.5.5
  • Database: MariaDB 10.11.16
  • DDEV: v1.25.2
  • DropzoneJS: 8.x-2.11
  • Browser: Chrome

Prerequisites

  • The dropzone JavaScript library is installed in web/libraries/dropzone.
  • Enable the modules needed for a browser-based upload path:
ddev drush en dropzonejs dropzonejs_eb_widget entity_browser -y
ddev drush role:perm:add authenticated 'dropzone upload files' -y
  • Create a standalone entity browser at /dropzonejs-test-standalone using the dropzonejs_media_entity widget, pointing at the image media type (same shape as entity_browser.browser.dropzonejs_eb_standalone_test.yml shipped in tests/modules/dropzonejs_test).
  • Log in as an administrator: ddev drush uli

Steps

  1. Before applying the fix, visit /dropzonejs-test-standalone, upload an image and press Select entities. Confirm the upload succeeds and a media item is created.
  2. Apply the fix from MR !36: UploadController uses AutowireTrait with promoted constructor properties instead of a manual create(), injects RequestStack instead of the current Request, dropzonejs.services.yml gains an autowiring alias for UploadHandlerInterface, and the kernel test builds the controller through the container.
  3. Rebuild caches: ddev drush cr
  4. Repeat the upload at /dropzonejs-test-standalone: drop an image into the dropzone and press Select entities.
  5. Run the kernel test coverage:
ddev exec vendor/bin/phpunit -c web/core/phpunit.xml.dist \
  web/modules/contrib/dropzonejs/tests/src/Kernel/DropzoneJsUploadControllerTest.php

Expected results

  • The upload route /dropzonejs/upload keeps working after the refactor — no 500 error, the thumbnail appears and the media item is created.
  • The controller can be built from the container without a manual create() method.
  • DropzoneJsUploadControllerTest passes and now exercises the real DI wiring.

Actual results

Before the fix, uploads through the standalone entity browser worked as expected with the hand-wired create(). After applying MR !36, the behaviour is unchanged in the browser: the file uploads, the preview renders and Select entities creates the media item, with no error on /dropzonejs/upload. Building the controller through the container resolves cleanly, which confirms the autowiring alias for Drupal\dropzonejs\UploadHandlerInterface added in dropzonejs.services.yml fixes the 500 reported against the first pass of this MR. The kernel test passes (2 tests, 15 assertions); the reported deprecations come from core's FileSystem::basename() and are unrelated to this change.


Testing produced with the assistance of an LLM.