ไฟล์ชั่วคราวถูกจัดการโดย file_file_download()
การดำเนินการของ hook_file_download()
ทำได้จากโมดูลไฟล์ รหัสที่ใช้คือรหัสต่อไปนี้
// ค้นหาว่ายังมีการใช้ไฟล์ชั่วคราวในระบบหรือไม่
ถ้า ($file->isTemporary()) {
$usage = \Drupal::service('file.usage')->listUsage($file);
ถ้า (ว่าง($usage) && $file->getOwnerId() != \Drupal::currentUser()
->รหัส()) {
// ปฏิเสธการเข้าถึงไฟล์ชั่วคราวโดยไม่มีการใช้งานที่ไม่ใช่ของ
// ผู้ใช้คนเดียวกัน ซึ่งจะป้องกันปัญหาด้านความปลอดภัยที่ไฟล์ส่วนตัวนั้น
// ได้รับการคุ้มครองโดยการอนุญาตของฟิลด์จะพร้อมใช้งานหลังจากการใช้งาน
// ถูกลบออกและก่อนที่จะถูกลบออกจากระบบไฟล์จริง
// โมดูลที่ขึ้นอยู่กับลักษณะการทำงานนี้ควรทำให้ไฟล์เป็นแบบถาวร
// แทน.
กลับ -1;
}
}
การอ่านความคิดเห็นที่ทำขึ้นเพื่อหลีกเลี่ยงไฟล์ส่วนตัว ซึ่งได้รับการป้องกันโดยสิทธิ์ของฟิลด์ จะมองเห็นได้หลังจากเปลี่ยนสิทธิ์ของฟิลด์ แต่ก่อนที่ไฟล์จะถูกลบ
ดูรหัสที่เรียกใช้ hook นั้นใน FileDownloadController::download()
ตัวอย่างเช่น ฉันไม่เห็นวิธีหลีกเลี่ยง เนื่องจากรหัสไม่ได้ใช้ hook_file_download_alter()
.
วิธีแก้ไขปัญหาคือตั้งค่าไฟล์นั้นว่ากำลังใช้งาน เนื่องจากรหัสจะตรวจสอบไฟล์ว่าไม่ได้ใช้ ก่อนที่จะบล็อกการเข้าถึง
ฟังก์ชัน mymodule_file_download($uri) {
ถ้า (StreamWrapperManager::getScheme($uri) == 'ชั่วคราว') {
ถ้า ($files = \Drupal::entityTypeManager()->getStorage('file')->loadByProperties(['uri' => $uri])){
ถ้า ($file = รีเซ็ต ($files)) {
// อนุญาตการเข้าถึง
\Drupal::service('file.usage')->add($file, 'mymodule', 'unexisting_entity', 10);
$headers = file_get_content_headers($ไฟล์);
กลับหัว $;
}
}
}
}
ฉันใช้ 'unexisting_entity'
และ 10 เป็นประเภทเอนทิตีและรหัสเอนทิตี หากคุณมีค่าที่แท้จริงสำหรับพวกเขา คุณควรใช้สิ่งเหล่านั้น
โปรดทราบว่า FileUsageBase::add()
, DatabaseFileUsageBackend::add()
วิธีพาเรนต์ ให้เปลี่ยนไฟล์เป็นแบบถาวร ในกรณีที่ยังไม่ได้ทำ
// ตรวจสอบให้แน่ใจว่าไฟล์ที่ใช้เป็นแบบถาวร
ถ้า (!$file->isPermanent()) {
$file->setPermanent();
$file->save();
}
เมื่อการใช้งานไฟล์ลดลงและกลายเป็น 0 ไฟล์จะเปลี่ยนเป็นชั่วคราวจาก FileUsageBase::ลบ()
.
// หากไม่มีการใช้งานไฟล์นี้เหลืออยู่ ให้ทำเครื่องหมายเป็นไฟล์ชั่วคราว
// ซึ่งส่งผลให้เกิดการลบผ่าน system_cron()
$usage = \Drupal::service('file.usage')->listUsage($file);
ถ้า (ว่าง ($ การใช้งาน)) {
$file->setTemporary();
$file->save();
}
ฉันอยากจะเพิ่มการใช้ไฟล์ แทนที่จะสร้างไฟล์ถาวรโดยตรง เนื่องจากการลดการใช้ไฟล์จะไม่ขัดแย้งกับโมดูลอื่นๆ ที่สามารถตั้งค่าไฟล์เดียวกันเป็นแบบถาวรได้
หรือฉันจะใช้รหัสต่อไปนี้สำหรับ hook_file_download()
.
ฟังก์ชัน mymodule_file_download($uri) {
ถ้า (StreamWrapperManager::getScheme($uri) == 'ชั่วคราว') {
ถ้า ($files = \Drupal::entityTypeManager()->getStorage('file')->loadByProperties(['uri' => $uri])){
ถ้า ($file = รีเซ็ต ($files)) {
// อนุญาตการเข้าถึง
ถ้า (!$file->isPermanent()) {
$file->setPermanent();
$file->save();
}
$headers = file_get_content_headers($ไฟล์);
กลับหัว $;
}
}
}
}
ในกรณีนี้ หากต้องการสร้างไฟล์ชั่วคราวอีกครั้ง ฉันจะใช้รหัสต่อไปนี้
// เก็บการอ้างอิงเอนทิตีของไฟล์ไว้ใน $file
$usage = \Drupal::service('file.usage')->listUsage($file);
ถ้า (ว่าง ($ การใช้งาน) && !$file->isTemporary()) {
$file->setTemporary();
$file->save();
}
เพื่อให้บรรลุตามที่คุณต้องการ คุณยังสามารถเปลี่ยนคอนโทรลเลอร์สำหรับ ระบบชั่วคราว เส้นทาง แต่นั่นดูมากเกินไป