Các tập tin tạm thời được xử lý bởi file_file_download()
, một triển khai của hook_file_download()
được thực hiện từ mô-đun Tệp. Mã nó sử dụng là mã sau đây.
// Tìm hiểu xem một tệp tạm thời có còn được sử dụng trong hệ thống hay không.
nếu ($file->isTemporary()) {
$usage = \Drupal::service('file.usage')->listUsage($file);
if (empty($usage) && $file->getOwnerId() != \Drupal::currentUser()
->id()) {
// Từ chối quyền truy cập vào các tệp tạm thời không sử dụng mà không thuộc sở hữu của
// cùng một người dùng. Điều này ngăn chặn sự cố bảo mật mà một tệp riêng tư
// được bảo vệ bởi các quyền của trường sẽ khả dụng sau khi sử dụng
// đã bị xóa và trước khi nó thực sự bị xóa khỏi hệ thống tệp.
// Các mô-đun phụ thuộc vào hành vi này sẽ làm cho tệp trở nên vĩnh viễn
// thay thế.
trả về -1;
}
}
Việc đọc các nhận xét được thực hiện nhằm mục đích tránh tệp riêng tư, được bảo vệ bởi quyền của trường, hiển thị sau khi quyền của trường được thay đổi nhưng trước khi tệp bị xóa.
Nhìn vào mã gọi hook đó, trong FileDownloadController::download()
ví dụ: tôi không thấy cách nào để tránh điều đó, vì mã không sử dụng hook_file_download_alter()
.
Một giải pháp thay thế có thể là đặt tệp đó là đang được sử dụng vì mã kiểm tra tệp không được sử dụng trước khi chặn quyền truy cập.
hàm mymodule_file_download($uri) {
if (StreamWrapperManager::getScheme($uri) == 'tạm thời') {
if ($files = \Drupal::entityTypeManager()->getStorage('file')->loadByProperties(['uri' => $uri])){
nếu ($file = reset($files)) {
// Quyền truy cập được cấp.
\Drupal::service('file.usage')->add($file, 'mymodule', 'uncurrent_entity', 10);
$headers = file_get_content_headers($file);
trả lại tiêu đề $;
}
}
}
}
tôi đã sử dụng 'thực thể không tồn tại'
và 10 là loại thực thể và ID thực thể. Nếu bạn có giá trị thực sự cho chúng, bạn nên sử dụng chúng.
Lưu ý rằng FileUsageBase::add()
, các DatabaseFileUsageBackend::add()
phương thức cha, thay đổi tệp thành vĩnh viễn, trong trường hợp chưa có.
// Đảm bảo rằng tệp được sử dụng là vĩnh viễn.
if (!$file->isPermanent()) {
$file->setPermanent();
$file->save();
}
Khi mức sử dụng tệp giảm xuống và trở thành 0, tệp được thay đổi thành tạm thời từ FileUsageBase::delete()
.
// Nếu không còn tập tin nào được sử dụng nữa, hãy đánh dấu nó là tạm thời,
// dẫn đến việc xóa thông qua system_cron().
$usage = \Drupal::service('file.usage')->listUsage($file);
nếu (trống ($ sử dụng)) {
$file->setTemporary();
$file->save();
}
Tôi muốn tăng mức sử dụng tệp, thay vì trực tiếp biến tệp thành vĩnh viễn, vì việc giảm mức sử dụng tệp không xung đột với các mô-đun khác có thể đặt cùng một tệp là vĩnh viễn.
Ngoài ra, tôi sẽ sử dụng mã sau đây cho hook_file_download()
.
hàm mymodule_file_download($uri) {
if (StreamWrapperManager::getScheme($uri) == 'tạm thời') {
if ($files = \Drupal::entityTypeManager()->getStorage('file')->loadByProperties(['uri' => $uri])){
nếu ($file = reset($files)) {
// Quyền truy cập được cấp.
if (!$file->isPermanent()) {
$file->setPermanent();
$file->save();
}
$headers = file_get_content_headers($file);
trả lại tiêu đề $;
}
}
}
}
Trong trường hợp này, để tạo lại tệp tạm thời, tôi sẽ sử dụng đoạn mã sau.
// Lưu trữ tham chiếu thực thể tệp trong $file.
$usage = \Drupal::service('file.usage')->listUsage($file);
if (trống($usage) && !$file->isTemporary()) {
$file->setTemporary();
$file->save();
}
Để đạt được những gì bạn muốn, cũng có thể thay đổi bộ điều khiển cho system.temporary tuyến đường, nhưng điều đó có vẻ quá mức.