Reputation: 13
I'm trying to understand how the /system/files route works in Drupal 10 (or 9).
My goal is to get a controller for a path which can have an unknown amount of subfolders and should stream files like /system/files does (with some custom behavior and permission checks).
The route would be
/some/prefix/{node}/{filepath}
but for testing I just tried /some/prefix/{filepath}
First I created a path processor:
<?php
namespace Drupal\mymodule\PathProcessor;
use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
use Symfony\Component\HttpFoundation\Request;
class PathProcessorFiles implements InboundPathProcessorInterface {
/**
* {@inheritdoc}
*/
public function processInbound($path, Request $request) {
if (str_starts_with($path, '/some/prefix/') && !$request->query->has('file') && preg_match('|^/some/prefix/(\d+)/(.+)|', $path, $matches)) {
$request->query->set('node_id', $matches[1]);
$request->query->set('file', $matches[2]);
return '/some/prefix';
}
return $path;
}
}
And a service:
mymodule.files:
class: Drupal\mymodule\PathProcessor\PathProcessorFiles
tags:
- { name: path_processor_inbound, priority: 200 }
Next a controller and route:
<?php
namespace Drupal\mymodule\Controller;
use Drupal\Core\Controller\ControllerBase;
class FilesController extends ControllerBase {
public function get() {
// Just some test.
return [
'#markup' => 'Test',
'#cache' => [
'max-age' => 0,
],
];
}
}
mymodule.file_download:
path: '/some/prefix/{filepath}'
defaults:
_controller: '\Drupal\mymodule\FilesController::get'
requirements:
filepath: .+
_access: 'TRUE'
While the path processor hits and finds the correct path, I get a "page not found" error. I don't understand how this process works and what I'm missing. And where the FileDownloadController::download() get the request param from.
Upvotes: 0
Views: 147
Reputation: 121
I'm not following your path processor regex, etc. so I've reverted to a simpler version from the original PathProcessorFiles.php
processor (/system/files)
public function processInbound($path, Request $request) {
if (strpos($path, '/some/prefix/') === 0) {
$file_path = preg_replace('|^\/some/prefix\/|', '', $path);
$request->query->set('file', $file_path);
return '/some/prefix';
}
return $path;
}
Then include HttpFoundation\Request in your controller so you can extract the variable that was set above $request->query->set('file', $file_path);
namespace Drupal\mymodule\Controller;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\Request; // added this
class FilesController extends ControllerBase {
public function get(Request $request) { // added this
// Just some test.
return [
'#markup' => 'Test '.$request->query->get('file'), // added this
'#cache' => [
'max-age' => 0,
],
];
}
}
I've been hacking at this all day, so not sure if it's the best solution.
Upvotes: 0