Why are $ _Files and/or HTTPFoundation\FileBag invalid in custom module Controller?
I have noticed a very strange issue with accessing an individual file from the $ _FILES
object or the Symfony derived \Symfony\Component\HTTPFoundation\FileBag
from within a custom module controller.
The exact location of the issue seems to be in Symfony\Component\HttpKernel\HttpKernel
-> handleRaw
Specifically, the file exists prior dispatching the KernelEvent::REQUEST
but it does not after.
// request $ event = new GetResponseEvent($ this, $ request, $ type); // THE FILE EXISTS HERE // file_exists( $ request->files->get(0)->getRealPath()) == TRUE $ this->dispatcher->dispatch(KernelEvents::REQUEST, $ event); // THE FILE DOES NOT EXISTS HERE // file_exists( $ request->files->get(0)->getRealPath()) == FALSE
Here is the entire method for reference also including some code to move the file, which works as expected as long as it is before the event dispatch.
/** * Handles a request to convert it to a response. * * Exceptions are not caught. * * @param Request $ request A Request instance * @param int $ type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST) * * @return Response A Response instance * * @throws \LogicException If one of the listener does not behave as expected * @throws NotFoundHttpException When controller cannot be found */ private function handleRaw(Request $ request, $ type = self::MASTER_REQUEST) { $ this->requestStack->push($ request); $ directory = \Drupal::service('file_system')->realpath(file_default_scheme() . "://"); /* @var \Symfony\Component\HttpFoundation\File\UploadedFile $ uploadedFile*/ $ uploadedFile = $ request->files->get(0); if (is_uploaded_file($ uploadedFile->getRealPath())){ $ success = $ uploadedFile->move($ directory); } // request $ event = new GetResponseEvent($ this, $ request, $ type); $ this->dispatcher->dispatch(KernelEvents::REQUEST, $ event); if ($ event->hasResponse()) { return $ this->filterResponse($ event->getResponse(), $ request, $ type); } // load controller if (false === $ controller = $ this->resolver->getController($ request)) { throw new NotFoundHttpException(sprintf('Unable to find the controller for path "%s". The route is wrongly configured.', $ request->getPathInfo())); } $ event = new FilterControllerEvent($ this, $ controller, $ request, $ type); $ this->dispatcher->dispatch(KernelEvents::CONTROLLER, $ event); $ controller = $ event->getController(); // controller arguments $ arguments = $ this->argumentResolver->getArguments($ request, $ controller); $ event = new FilterControllerArgumentsEvent($ this, $ controller, $ arguments, $ request, $ type); $ this->dispatcher->dispatch(KernelEvents::CONTROLLER_ARGUMENTS, $ event); $ controller = $ event->getController(); $ arguments = $ event->getArguments(); // call controller $ response = call_user_func_array($ controller, $ arguments); // view if (!$ response instanceof Response) { $ event = new GetResponseForControllerResultEvent($ this, $ request, $ type, $ response); $ this->dispatcher->dispatch(KernelEvents::VIEW, $ event); if ($ event->hasResponse()) { $ response = $ event->getResponse(); } if (!$ response instanceof Response) { $ msg = sprintf('The controller must return a response (%s given).', $ this->varToString($ response)); // the user may have forgotten to return something if (null === $ response) { $ msg .= ' Did you forget to add a return statement somewhere in your controller?'; } throw new \LogicException($ msg); } } return $ this->filterResponse($ response, $ request, $ type); }
I am trying to write a custom GraphQL module
mutation plugin that handles file uploads and unless I can get access to the file object from the POST request, I don’t think this will be possible.
Any thoughts are greatly appreciated.