Forums / National / Russian / Тех. поддержка / [Решено] Как привязать изображения модулю Files, которые сохраняются по url

prostogorod
#1 2024-11-08 16:03

Пишу скрипт обработки xml-файла. С категориями и почти с товарами разобрался. Осталось реализовать прикрепление изображение к товарам. Вернее дошел до того, что все изображения товаров сохраняю на сервер по url. Но я хочу привязать к модулю Files.
Пожалуйста, подскажите, какие функции использовать в модуле Files для сохранения изображений? Какая последовательность?
А лучше кратко в виде кода, так будет более понятней)) Спасибо!

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Получаем содержимое изображения
$imageContent = fetchImage((string)$pictureUrl);
 
// Генерируем уникальное имя файла
$imageFileName = 'image_' . uniqid() . '.jpg';
$fullImagePath = $savePath . '/' . $imageFileName;   /////////////////
 
// Сохраняем изображение в файл
file_put_contents($fullImagePath, $imageContent);
 
// Проверяем, сохранилось ли изображение
if (file_exists($fullImagePath)) 
{
    if (cot_module_active('files')) 
    {
        require_once cot_incfile('files', 'module'); 
        ......
    }
 
}

 

P.S. Хочу учесть, один нюанс. Товары уже загружены, теперь нужно прикрепить изображение к ним. Я изначально разделил обработку на добавление категорий, потом товаров и теперь изображений. Вообще вся задача обработки xml-файла ресурсоёмкая. Что еще посоветуете сделать, чтобы процесс ускорить и минимизировать ресурсы сервера? В том числе и при обработке изображений?

This post was edited by Alex300 (2025-02-11 23:42, 5 months ago)
Alex300
#2 2024-11-09 07:19

Судя по коду Вы загружаете изображение в память, а потом записываете на диск. Можно использовать функцию copy(). Она умеет копировать удаленные файлы.

PHP
1
2
3
4
5
6
7
if (@copy('http://someserver.com/somefile.jpg','./somefile.jpg')) {
        echo "File copied from remote!";
} else {
    $errors = error_get_last();
    echo 'COPY ERROR: ' . $errors['type'];
    echo '<br />\n' . $errors['message'];
}

Сэкономите память не загружая в нее данные, которые не собираетесь обрабатывать. Фактически файл при скачивании все равно будет загружен в память, но при сохранении на диск память будет освобождена. И это не расходует память, выделяемую скрипту на выполнение.

// Проверяем, сохранилось ли изображение
if (file_exists($fullImagePath))

Это лишнее. Функция copy() вернет TRUE в случае успеха и FALSE в противном случае. Достаточно проверить результат выполнения функции.

PHP в режиме командной строки как правило не имеет ограничений по памяти и времени выполнения. Этот компонент позволяет запускать Cotonti из командной строки.

Не накапливайте в памяти ненужные данные. После обработки каждого товара в памяти не должно оставаться "мусора". Ненужные более данные должны быть удалены или перезаписаны следующим товаром.

 

Модуль файлов используется в основном для удобной загрузки файлов и привязки их к объектам (страницы, посты, товары и т.п.) через веб интерфейс и для удобного вывода файлов в веб интерфейсе. Загрузка у Вас автоматизирована. Если вы не собираетесь выводить каталог товаров в браузер - особого смысла нет.

 

Если он все же нужен, у него нет отдельного метода для сохранения файла, который существует локально (надо бы сделать). Но можно написать примерно так:
 

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// $fullImagePath - Путь к файлу локально из Вашего примера
 
$file = new File();
$file->original_name = $originalName; // Исходное имя файла (используется для отображения пользователю)
$file->user_id = $uid;
$file->source = 'shop';
$file->source_id = $product->id; // ID сохраненного товара
$file->ext = mb_strtolower(cot_filesGetExtension($fullImagePath));
$file->mime_type = mime_content_type($fullImagePath);
$file->is_img = 1;
$file->size = filesize($fullImagePath));
 
 
Cot::$db->beginTransaction();
try {
    $fileId = $file->save();
    if (!fileId) {
        throw new Exception('Ошибка при сохранении');
    }
     
    // Path relative to files root directory
    $relativeFileName = FileService::generateFileRelativePath($objFile);
    $file->path = dirname($relativeFileName);
    $file->file_name = basename($relativeFileName);
    $file->filesystem_name = FileService::getFilesystemName($file->source, $file->source_field);
      
    // Path relative to site root directory
    $fileFullName = Cot::$cfg['files']['folder'] . '/' . $relativeFileName;
    if (!@rename($fullImagePath, $fileFullName)) {
        throw new Exception('Ошибка при сохранении');
    }
      
    $file->save();
      
    Cot::$db->commit();
} catch(\Throwable $e) {
    Cot::$db->rollBack();
    // не удалось сохранить файл;
}

 

Есть миры, не здесь, там, где небеса горят, и моря засыпают, и реки дремлют; люди сделаны из дыма, а города – из песен. Где-то опасность, где-то несправедливость, даже где-то остыл чай. Идем Эйс, у нас много работы!...
...Sorry for my english...
Бесплатные расширения для Cotonti: https://lily-software.com/free-scripts/
This post was edited by Alex300 (2024-11-09 07:29, 8 months ago)
prostogorod
#3 2024-11-09 18:16

Спасибо! Буду пробовать. Но у меня сразу ошибка:

PHP
1
Fatal error: Uncaught Error: Class "File" not found in ...

Я так понимаю нужно еще дополнительно класс File подключить?

Такого подключения не достаточно?

PHP
1
require_once cot_incfile('files', 'module');

 

 И еще вдогонку вопрос, по коду не понял. Для каждого товара, может быть одно или несколько изображений.  Я это учитываю, и у меня переменная - $id_attach, которая считает количество изображений для каждого товара. Как эту переменную учитывать, на примере Вашего кода?
 

PHP
1
 $imageFileName = 'image-'. $id . '-' .  $id_attach . '-' . uniqid() . '.jpg';

 

This post was edited by prostogorod (2024-11-09 19:57, 8 months ago)
Alex300
#4 2024-11-10 11:50

Забыл написать. В начале php-файла надо добавить:

PHP
1
use cot\modules\files\models\File;

Примерно так:

PHP
1
2
3
4
5
<?php
 
use cot\modules\files\models\File;
 
defined('COT_CODE') or die('Wrong URL.');

 

Для каждого товара, может быть одно или несколько изображений.

Несколько

Есть миры, не здесь, там, где небеса горят, и моря засыпают, и реки дремлют; люди сделаны из дыма, а города – из песен. Где-то опасность, где-то несправедливость, даже где-то остыл чай. Идем Эйс, у нас много работы!...
...Sorry for my english...
Бесплатные расширения для Cotonti: https://lily-software.com/free-scripts/
prostogorod
#5 2024-11-10 15:22

Требовало, добавил еще

PHP
1
use cot\modules\files\services\FileService;

Спасибо за помощь! Заработало. Файлы прикрепляет, теперь нужно осознать, что с этим можно еще сделать.

This post was edited by prostogorod (2024-11-10 22:54, 8 months ago)