Налаштування завантаження сертифікатів на товари у 1С-Bitrix
Різниця між відображенням і завантаженням сертифікатів — не тільки в кнопці «Завантажити». Правильна настройка завантаження передбачає: контроль доступу до файлів, коректні імена файлів при завантаженні, захист від прямого перебору URL, та при необхідності — облік завантажень.
Прямі посилання vs. контроль відача файлів
Якщо файли зберігаються у /upload/ — прямі посилання працюють, але будь-хто, хто знає URL, завантажить файл без авторизації. Для публічних сертифікатів це нормально. Для внутрішніх документів — ні.
Пряме посилання (найпростіший варіант):
$fileInfo = \CFile::GetFileArray($fileId);
echo '<a href="' . $fileInfo['SRC'] . '" download>';
Контрольована відача через обробник (якщо потрібен контроль доступу або гарні імена файлів):
Створюєте файл /local/ajax/download-cert.php:
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';
$fileId = (int)$_GET['id'];
$productId = (int)$_GET['product_id'];
// Перевіряємо, що файл реально привязан до товару (захист від перебору)
$prop = \CIBlockElement::GetProperty(
CATALOG_IBLOCK_ID,
$productId,
[],
['CODE' => 'CERTIFICATE']
);
$allowed = false;
while ($p = $prop->Fetch()) {
if ((int)$p['VALUE'] === $fileId) {
$allowed = true;
break;
}
}
if (!$allowed) {
header('HTTP/1.0 403 Forbidden');
die();
}
$fileInfo = \CFile::GetFileArray($fileId);
if (!$fileInfo) {
header('HTTP/1.0 404 Not Found');
die();
}
$filePath = $_SERVER['DOCUMENT_ROOT'] . $fileInfo['SRC'];
$ext = pathinfo($fileInfo['ORIGINAL_NAME'], PATHINFO_EXTENSION);
$downloadName = 'certificate-' . $productId . '.' . $ext;
header('Content-Type: ' . $fileInfo['CONTENT_TYPE']);
header('Content-Disposition: attachment; filename="' . $downloadName . '"');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
exit();
Посилання для завантаження:
<a href="/local/ajax/download-cert.php?id=<?= $fileId ?>&product_id=<?= $productId ?>">
Завантажити сертифікат
</a>
Облік завантажень
Якщо потрібно знати, скільки разів завантажували сертифікат, — логуєте в окрему таблицю або через події Bitrix. Найпростіший варіант — таблиця b_user_counter не підходить за семантикою, робите свою через \Bitrix\Main\Application::getConnection()->query() або створюєте HL-інфоблок CertDownloads з полями: UF_PRODUCT_ID, UF_FILE_ID, UF_USER_ID, UF_DATE, UF_IP.
Пакетне завантаження кількох сертифікатів
Якщо у товара кілька сертифікатів і хочете запропонувати завантажити всі одним ZIP — використовуєте PHP ZipArchive:
$zip = new ZipArchive();
$tmpFile = tempnam(sys_get_temp_dir(), 'certs_');
$zip->open($tmpFile, ZipArchive::CREATE);
foreach ($fileIds as $fid) {
$fi = \CFile::GetFileArray($fid);
$zip->addFile($_SERVER['DOCUMENT_ROOT'] . $fi['SRC'], $fi['ORIGINAL_NAME']);
}
$zip->close();
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="certificates.zip"');
readfile($tmpFile);
unlink($tmpFile);
Захист папки upload
Якщо хочете повністю закрити прямий доступ до файлів у папці — кладете їх у /upload/protected/ і додаєте у .htaccess цієї папки:
Deny from all
Тоді все завантаження йде лише через ваш обробник, прямі URL не працюють.
| Етап | Час |
|---|---|
| Настройка прямих посилань на завантаження | 1–2 ч |
| Розробка контрольованого обробника | 3–5 ч |
| Облік завантажень (опціонально) | 2–3 ч |
| Пакетне завантаження ZIP (опціонально) | 2–4 ч |







