Как вывести прямую ссылку на файл из раздела загрузок в header.twig ?

F

Feetrus9836

Шопмейкер
#1
добрый день
такой вопрос, может кто уже делал
мне нужно в админке загружать файл pdf и выводить ссылку на него в header.twig
была мысль сделать через раздел загрузок, но там нельзя получить прямую ссылку на скачивания файла
делать черещ кастомное поле с настройках магазина?
 
Baco

Baco

architect
#2
получить прямую ссылку на скачивания файла
а для чого прямий лінк на завантаження ?
ось накинув простеньке рішення, спешл для цієї задачки, писав на ентузіазмі та імпровізації, тому, якщо допомогло, прошу не бути байдужими та допомогти форуму навзаєм (відео та архів прикріплюю з детальним роз'ясненням)
крок 0: додаємо додаткове поле в таблицю завантаження
PHP:
ALTER TABLE `oc_download` ADD `main` TINYINT(1) NOT NULL DEFAULT '0' AFTER `mask`;
 

Вкладення

OP
F

Feetrus9836

Шопмейкер
Thread Starter #3
Ссылка в меню добавляется?
суть такая, сайт ресторана, они в pdf раньше по фтп обновляли меню, теперь хотят из админки это делать
ссылка на меню выводится возле логотипа
 
Baco

Baco

architect
#4
посилання разом в меню, якщо розумієш код, то підправити куди треба сам массив downloads можна в будь яке місце, хоч окремим пунктом в меню через список ul->li, чіркани в ПП, підкажу що до чого
 
OP
F

Feetrus9836

Шопмейкер
Thread Starter #5
это как то сложно для простого сайта
я видел это так
в разделе настройки магазина - поле загрузки файла, это поле ajax загружает в какую то папку этот файл, путь к файлу записывается в базу, в header потом просто выводится с базы {{ link_menu_file }}
если загружают другой файл - то в базе значение перезаписывается
 
OP
F

Feetrus9836

Шопмейкер
Thread Starter #6
есть вариант решения , но думаю, что нужно правильнее сделать "по опенкарту", таксказать

HTML:
<form id="upload-form" method="post" enctype="multipart/form-data">
  <input type="file" name="file" id="file">
  <!-- другие поля формы -->
  <input type="submit" value="Загрузить">
</form>
JavaScript:
$(document).ready(function() {
  $('#upload-form').submit(function(event) {
    event.preventDefault(); // отменяем стандартное действие формы
    var formData = new FormData(this); // создаем объект FormData для отправки данных формы
    $.ajax({
      url: 'upload.php', // адрес обработчика на сервере
      type: 'POST',
      data: formData, // данные формы
      processData: false, // не обрабатываем данные FormData
      contentType: false, // не устанавливаем тип содержимого
      success: function(response) {
        // обрабатываем ответ от сервера
        console.log(response);
      },
      error: function(jqXHR, textStatus, errorThrown) {
        // обрабатываем ошибки при отправке запроса
        console.log(textStatus, errorThrown);
      }
    });
  });
});
PHP:
<?php
// подключаемся к базе данных
$db = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');

// проверяем, был ли загружен файл
if (isset($_FILES['file']) && $_FILES['file']['error'] == UPLOAD_ERR_OK) {
  // получаем информацию о файле
  $fileName = $_FILES['file']['name'];
  $fileSize = $_FILES['file']['size'];
  $fileType = $_FILES['file']['type'];
  $fileTemp = $_FILES['file']['tmp_name'];

  // загружаем файл на сервер
  move_uploaded_file($fileTemp, 'uploads/' . $fileName);

  // записываем путь к файлу в базу данных
  $stmt = $db->prepare('INSERT INTO files (name, size, type, path) VALUES (?, ?, ?, ?)');
  $stmt->execute([$fileName, $fileSize, $fileType, 'uploads/' . $fileName]);

  // возвращаем сообщение об успешной загрузке файла
  echo 'Файл успешно загружен и записан в базу данных.';
} else {
  // возвращаем сообщение об ошибке загрузки файла
  echo 'Ошибка загрузки файла: ' . $_FILES['file']['error'];
}
?>
 
Baco

Baco

architect
#7
форм завантаження є багато, але таке використовувати, це замовника не поважати, я вже бачу порушення безпеки, тому прошу, описати попунктно задачу, що не так і як повинно бути, і спробую розписати покроково, як би я це реалізував.
але найпростіший варіант, якщо потрібно виводити файли через адмінку, то той, що по відео оформив, можна його адаптувати під потреби, розуміти б масштабно задачу.
 
OP
F

Feetrus9836

Шопмейкер
Thread Starter #8
маштабной задачи просто нету
все просто
из админки нужно загружать только один файл и выводить ссылку на него в header
 
OP
F

Feetrus9836

Шопмейкер
Thread Starter #10
HTML:
<div class="form-group">
 <label class="col-sm-2 control-label" for="input-name">Обновить меню</label>
<div class="col-sm-10"><input type="file" id="menu-file" class="form-control" autocomplete="off"></div>
<div class="col-sm-2"></div><div class="col-sm-10"><div id="result"></div></div>
</div>
JavaScript:
$("#menu-file").change(function(){
                                        if (window.FormData === undefined) {
                                            alert('В вашем браузере FormData не поддерживается')
                                        } else {
                                            var formData = new FormData();
                                            formData.append('file', $("#menu-file")[0].files[0]);

                                            $.ajax({
                                                type: "POST",
                                                url: '/upload-form-menu.php',
                                                cache: false,
                                                contentType: false,
                                                processData: false,
                                                data: formData,
                                                dataType : 'json',
                                                success: function(msg){
                                                    if (msg.error == '') {
                                                        $('#result').html(msg.success);
                                                    } else {
                                                        $('#result').html(msg.error);
                                                    }
                                                }
                                            });
                                        }
                                    });
PHP:
<?php
$db = new PDO('mysql:host=localhost;dbname=testoc', 'root', '');
 
// Название <input type="file">
$input_name = 'file';
 
// Разрешенные расширения файлов.
$allow = array(
    'pdf'
);
 
// Запрещенные расширения файлов.
$deny = array(
    'phtml', 'php', 'php3', 'php4', 'php5', 'php6', 'php7', 'phps', 'cgi', 'pl', 'asp',
    'aspx', 'shtml', 'shtm', 'htaccess', 'htpasswd', 'ini', 'log', 'sh', 'js', 'html',
    'htm', 'css', 'sql', 'spl', 'scgi', 'fcgi', 'exe'
);
 
// Директория куда будут загружаться файлы.
$path = __DIR__ . '/uploads/';
 
 
$error = $success = '';
if (!isset($_FILES[$input_name])) {
    $error = 'Файл не загружен.';
} else {
    $file = $_FILES[$input_name];
 
    // Проверим на ошибки загрузки.
    if (!empty($file['error']) || empty($file['tmp_name'])) {
        $error = 'Не удалось загрузить файл.';
    } elseif ($file['tmp_name'] == 'none' || !is_uploaded_file($file['tmp_name'])) {
        $error = 'Не удалось загрузить файл.';
    } else {
        // Оставляем в имени файла только буквы, цифры и некоторые символы.
        $pattern = "[^a-zа-яё0-9,~!@#%^-_\$\?\(\)\{\}\[\]\.]";
        $name = mb_eregi_replace($pattern, '-', $file['name']);
        $name = mb_ereg_replace('[-]+', '-', $name);
        $parts = pathinfo($name);
 
        if (empty($name) || empty($parts['extension'])) {
            $error = 'Недопустимый тип файла';
        } elseif (!empty($allow) && !in_array(strtolower($parts['extension']), $allow)) {
            $error = 'Недопустимый тип файла';
        } elseif (!empty($deny) && in_array(strtolower($parts['extension']), $deny)) {
            $error = 'Недопустимый тип файла';
        } else {
            // Перемещаем файл в директорию.
            if (move_uploaded_file($file['tmp_name'], $path . $name)) {
                // Далее можно сохранить название файла в БД и т.п.
                $success = '<p style="color: green">Файл «' . $name . '» успешно загружен.</p>';
                // записываем путь к файлу в базу данных
                $stmt = $db->prepare('UPDATE oc_setting SET value = ? WHERE code = ? AND `key` = ?');
                $stmt->execute(['uploads/' . $name, 'config', 'config_file_patch']);
                
            } else {
                $error = 'Не удалось загрузить файл.';
            }
        }
    }
}
 
// Вывод сообщения о результате загрузки.
if (!empty($error)) {
    $error = '<p style="color: red">' . $error . '</p>'; 
}
 
$data = array(
    'error'   => $error,
    'success' => $success,
);
 
header('Content-Type: application/json');
echo json_encode($data, JSON_UNESCAPED_UNICODE);
exit();
 
Baco

Baco

architect
#11
тоді ось послідовність:
0. admin/view/template/setting/setting.twig знаходимо: <div class="tab-pane" id="tab-store"> і одразу після, на новому рядку вставляємо ось таку розмітку:
HTML:
<div class="form-group required">
        <label class="col-sm-2 control-label" for="input-pdf">{{ entry_pdf_file }}</label>
         <div class="col-sm-10">
                  <a onclick="startUpload();" id="uploader" class="btn btn-primary"><i class="fa fa-upload"></i> {{ button_import }}</a>
         </div>
</div>
1. в кінці файлу, знайти {{ footer }} та перед ним додати наступний код:
JavaScript:
<script type="text/javascript"><!--
    function startUpload() {
        var file_button = document.createElement('input');
        file_button.type = "file";
        file_button.id = "file_button1";
        file_button.style.display = "none";
        file_button.style.position = "absolute";
        file_button.onchange = function() {
            var form_data = new FormData();
            var file = jQuery(this).get(0).files[0];
            form_data.append('file', file);
            form_data.append('type', 'file');
            form_data.append('name', 'fileToUpload');
            setTimeout(function() {
                jQuery.ajax({
                    url: 'index.php?route=tool/upload/uploadToMenu&user_token={{ user_token }}',
                    type: 'post',
                    cache: false,
                    contentType: false,
                    processData: false,
                    data: form_data,
                    dataType: 'json',
                    beforeSend: function() {
                        $("#uploader").html('<img src="{{ store_url }}image/catalog/loader.gif" />');
                    },           
                    success: function(json) {
                        if (json['success']) {
                            $("#uploader").html('<span>' + json['success'] + '</span>');
                        }
                    }
                });
            }, 1000);
        };
        jQuery(document.body).append(file_button);
        file_button.click();
        jQuery("#file_button1").remove();
    }
//--></script>
2. і в фінальному завершенні додаємо метод для прямого завантаження в каталог малюнків та підкаталог files, для цього знаходимо файл: admin/controller/tool/upload.php і перед методом:
public function upload() { додаємо ось такий код:
PHP:
    public function uploadToMenu() {   
        $json = array();
        $this->load->language('sale/order');
        if (!$this->user->hasPermission('modify', 'tool/upload')) {
            $json['error'] = $this->language->get('error_permission');
        }
        if (!$json) {
            if (!empty($this->request->files['file']['name']) && is_file($this->request->files['file']['tmp_name'])) {
                $filename = html_entity_decode($this->request->files['file']['name'], ENT_QUOTES, 'UTF-8');
                if ((utf8_strlen($filename) < 3) || (utf8_strlen($filename) > 128)) {
                    $json['error'] = $this->language->get('error_filename');
                }
                $allowed = array();
                $extension_allowed = preg_replace('~\r?\n~', "\n", $this->config->get('config_file_ext_allowed'));
                $filetypes = explode("\n", $extension_allowed);
                foreach ($filetypes as $filetype) {
                    $allowed[] = trim($filetype);
                }
                if (!in_array(strtolower(substr(strrchr($filename, '.'), 1)), $allowed)) {
                    $json['error'] = $this->language->get('error_filetype');
                }
                $allowed = array();
                $mime_allowed = preg_replace('~\r?\n~', "\n", $this->config->get('config_file_mime_allowed'));
                $filetypes = explode("\n", $mime_allowed);
                foreach ($filetypes as $filetype) {
                    $allowed[] = trim($filetype);
                }
                if (!in_array($this->request->files['file']['type'], $allowed)) {
                    $json['error'] = $this->language->get('error_filetype');
                }
                $content = file_get_contents($this->request->files['file']['tmp_name']);
                if (preg_match('/\<\?php/i', $content)) {
                    $json['error'] = $this->language->get('error_filetype');
                }
                if ($this->request->files['file']['error'] != UPLOAD_ERR_OK) {
                    $json['error'] = $this->language->get('error_upload_' . $this->request->files['file']['error']);
                }
            } else {
                $json['error'] = $this->language->get('error_upload');
            }
        }
        if (!$json) {
            move_uploaded_file($this->request->files['file']['tmp_name'], DIR_IMAGE . 'files/' . $filename);
            $json['success'] = $this->language->get('text_upload');
        }
        $this->response->addHeader('Content-Type: application/json');
        $this->response->setOutput(json_encode($json));
    }
3. створіть каталог files у кореневому image
тепер завантажений в адмінці файл буде доступний за адресою: https://my_domen.ua/image/files/my_file.pdf

p.s. як вже в меню додавати, то не буду розписувати, якщо потрібно щоб посилання було статичним, то при завантаженні, не міняти назву файлу і завжди притримуватись цієї концепції + додайте в мовний файл змінну з назвою entry_pdf_file, щоб текст навпроти з'явився

якщо не хочеться перейматись про постійну зміну назви файлу і просто кожен раз завантажувати різні PDF файли і отримувати один лінк на файл, тоді поміняти ось цей рядок:
PHP:
move_uploaded_file($this->request->files['file']['tmp_name'], DIR_IMAGE . 'files/' . $filename);
на
PHP:
move_uploaded_file($this->request->files['file']['tmp_name'], DIR_IMAGE . 'files/catalog.pdf');
тоді файл стабільно буде доступним за адресою: https://my_domen.ua/image/files/catalog.pdf
 
Останнє редагування:
OP
F

Feetrus9836

Шопмейкер
Thread Starter #14
тоді ось послідовність:
0. admin/view/template/setting/setting.twig знаходимо: <div class="tab-pane" id="tab-store"> і одразу після, на новому рядку вставляємо ось таку розмітку:
HTML:
<div class="form-group required">
        <label class="col-sm-2 control-label" for="input-pdf">{{ entry_pdf_file }}</label>
         <div class="col-sm-10">
                  <a onclick="startUpload();" id="uploader" class="btn btn-primary"><i class="fa fa-upload"></i> {{ button_import }}</a>
         </div>
</div>
1. в кінці файлу, знайти {{ footer }} та перед ним додати наступний код:
JavaScript:
<script type="text/javascript"><!--
    function startUpload() {
        var file_button = document.createElement('input');
        file_button.type = "file";
        file_button.id = "file_button1";
        file_button.style.display = "none";
        file_button.style.position = "absolute";
        file_button.onchange = function() {
            var form_data = new FormData();
            var file = jQuery(this).get(0).files[0];
            form_data.append('file', file);
            form_data.append('type', 'file');
            form_data.append('name', 'fileToUpload');
            setTimeout(function() {
                jQuery.ajax({
                    url: 'index.php?route=tool/upload/uploadToMenu&user_token={{ user_token }}',
                    type: 'post',
                    cache: false,
                    contentType: false,
                    processData: false,
                    data: form_data,
                    dataType: 'json',
                    beforeSend: function() {
                        $("#uploader").html('<img src="{{ store_url }}image/catalog/loader.gif" />');
                    },          
                    success: function(json) {
                        if (json['success']) {
                            $("#uploader").html('<span>' + json['success'] + '</span>');
                        }
                    }
                });
            }, 1000);
        };
        jQuery(document.body).append(file_button);
        file_button.click();
        jQuery("#file_button1").remove();
    }
//--></script>
2. і в фінальному завершенні додаємо метод для прямого завантаження в каталог малюнків та підкаталог files, для цього знаходимо файл: admin/controller/tool/upload.php і перед методом:
public function upload() { додаємо ось такий код:
PHP:
    public function uploadToMenu() {  
        $json = array();
        $this->load->language('sale/order');
        if (!$this->user->hasPermission('modify', 'tool/upload')) {
            $json['error'] = $this->language->get('error_permission');
        }
        if (!$json) {
            if (!empty($this->request->files['file']['name']) && is_file($this->request->files['file']['tmp_name'])) {
                $filename = html_entity_decode($this->request->files['file']['name'], ENT_QUOTES, 'UTF-8');
                if ((utf8_strlen($filename) < 3) || (utf8_strlen($filename) > 128)) {
                    $json['error'] = $this->language->get('error_filename');
                }
                $allowed = array();
                $extension_allowed = preg_replace('~\r?\n~', "\n", $this->config->get('config_file_ext_allowed'));
                $filetypes = explode("\n", $extension_allowed);
                foreach ($filetypes as $filetype) {
                    $allowed[] = trim($filetype);
                }
                if (!in_array(strtolower(substr(strrchr($filename, '.'), 1)), $allowed)) {
                    $json['error'] = $this->language->get('error_filetype');
                }
                $allowed = array();
                $mime_allowed = preg_replace('~\r?\n~', "\n", $this->config->get('config_file_mime_allowed'));
                $filetypes = explode("\n", $mime_allowed);
                foreach ($filetypes as $filetype) {
                    $allowed[] = trim($filetype);
                }
                if (!in_array($this->request->files['file']['type'], $allowed)) {
                    $json['error'] = $this->language->get('error_filetype');
                }
                $content = file_get_contents($this->request->files['file']['tmp_name']);
                if (preg_match('/\<\?php/i', $content)) {
                    $json['error'] = $this->language->get('error_filetype');
                }
                if ($this->request->files['file']['error'] != UPLOAD_ERR_OK) {
                    $json['error'] = $this->language->get('error_upload_' . $this->request->files['file']['error']);
                }
            } else {
                $json['error'] = $this->language->get('error_upload');
            }
        }
        if (!$json) {
            move_uploaded_file($this->request->files['file']['tmp_name'], DIR_IMAGE . 'files/' . $filename);
            $json['success'] = $this->language->get('text_upload');
        }
        $this->response->addHeader('Content-Type: application/json');
        $this->response->setOutput(json_encode($json));
    }
3. створіть каталог files у кореневому image
тепер завантажений в адмінці файл буде доступний за адресою: https://my_domen.ua/image/files/my_file.pdf

p.s. як вже в меню додавати, то не буду розписувати, якщо потрібно щоб посилання було статичним, то при завантаженні, не міняти назву файлу і завжди притримуватись цієї концепції + додайте в мовний файл змінну з назвою entry_pdf_file, щоб текст навпроти з'явився

если два языка на сайте - то не работает корректно
какой то кеш может
 
Зверху