Обновление полей ресурсов на основе csv-файла иморта (modx 2.8.8 + minishop 2)

Задача была обновить поля у ресурсов (ресурсы: категории, товары; поля: основные, дополнительные (тв)).
Обновление изображений (галерея) в задачу не входило.
Возможно, кому-нибудь пригодится. Если будут корректировки/замечания, буду только рад.
Пытался использовать модуль importX, но оказалось,что существующий функционал модуля затирает все тв-поля, которых не было в csv-файле, но они были заполнены у ресурсов (вина не самого модуля, а процессора update, который он использует).

Решил данную задачу, немного изменив скрипт csv.php (/core/components/minishop2/import/csv.php). Большое спасибо его создателю за труд!

1. Пример файла импорта import.csv:
id;pagetitle;tv1;tv2
189;Заголовок Товар 1;Сео-заголовок для товара 1;Сео-описание для товара 1
320;Заголовок Категория 1;Сео-заголовок для для категории;Сео-описание для для категории
где id — id ресурса. Обязательное поле
Остальные поля — заполняются по необходимости. Если в файле какие-то поля пустые, то обновление по ним не произойдет.
Директория размещения файла импорта — любая папка в корне проекта, в нашем случае — import.

2. Вызов скрипта — через веб-интерфейс. Пример, вызова для нашего файла импорта:
[ваш домен]/import/csvUpdate.php?file=/import/import.csv&fields=id,pagetitle,tv1,tv2
Если разделитель полей отличен от ';', то необходимо указать параметр &delimeter=[ваш разделитель]
Директория размещения скрипта — любая папка в корне проекта, в нашем случае — import

3. Сам скрипт (csvUpdate.php):
<?php
const MODX_API_MODE = true;
require_once '../core/config/config.inc.php';
require_once MODX_BASE_PATH . 'index.php';

$file = @$_REQUEST['file'];
$fields = @$_REQUEST['fields'];
$delimeter = @$_REQUEST['delimeter'];
$is_debug = false;

// Load main services
/** @var modX $modx */
$modx->setLogLevel($is_debug ? modX::LOG_LEVEL_INFO : modX::LOG_LEVEL_ERROR);
$modx->getService('error', 'error.modError');

// Time limit
set_time_limit(600);
$tmp = 'Trying to set time limit = 600 sec: ';
$tmp .= ini_get('max_execution_time') == 600 ? 'done' : 'error';
$modx->log(modX::LOG_LEVEL_INFO, $tmp);

// Check required options
if (empty($fields)) {
    $modx->log(modX::LOG_LEVEL_ERROR, 'You must specify the parameter "fields". It needed for parse of your file.');
    exit;
}

$keys = array_map('trim', explode(',', strtolower($fields)));

$requiredField = 'id';
if (!in_array($requiredField, $keys)) {
    $modx->log(modX::LOG_LEVEL_ERROR, 'Field "' . $requiredField . '" not exists in csv file. Please fix import file');
    exit;
}

if (empty($delimeter)) {
    $delimeter = ';';
}

// Check file
if (empty($file)) {
    $error = 'You must specify an file in the ';
    $modx->log(modX::LOG_LEVEL_ERROR, $error);
    exit;
} elseif (!preg_match('/\.csv$/i', $file)) {
    $modx->log(modX::LOG_LEVEL_ERROR, 'Wrong file extension. File must be an *.csv.');
    exit;
}

$file = str_replace('//', '/', MODX_BASE_PATH . $file);
if (!file_exists($file)) {
    $modx->log(modX::LOG_LEVEL_ERROR, 'File not found at ' . $file . '.');
    exit;
}

// Import!
$handle = fopen($file, "r");
$rows = $updated = 0;
$not_updated = [];
$csv = fgetcsv($handle, 0, $delimeter);
while (($csv = fgetcsv($handle, 0, $delimeter)) !== false) {
    $rows++;
    $data = [];
    $dataTvs = [];
    $modx->error->reset();
    foreach ($keys as $k => $v) {
        if (!isset($csv[$k])) {
            exit('Field "' . $v . '" not exists in file. Please fix import file or parameter "fields".');
        }

        if (preg_match('/^tv(\d+)$/', $v)){
            $tvId = substr($v, 2);
            $dataTvs[$tvId] = $csv[$k];
        } else {
            $data[$v] = $csv[$k];
        }
    }

    // update resource
    $res = $modx->getObject('modResource', $data['id']);
    if ($res) {
        array_shift($data);
        if (!empty($data)) {
            foreach ($data as $key => $field) {
                if (empty($field)) {
                    continue;
                }
                $res->set($key, $field);
            }
            $res->save();
        }

        if (!empty($dataTvs)) {
            foreach ($dataTvs as $key => $field_tv) {
                if (empty($field_tv)) {
                    continue;
                }
                $res->setTVValue((int)$key, $field_tv);
            }
        }

        $updated++;
        $modx->log(modX::LOG_LEVEL_INFO, "Successfully updated");
    } else {
        $not_updated[] = $data['id'];
        $modx->log(modX::LOG_LEVEL_ERROR, "Error on update resource id={$data['id']}. It doesn't exist.\n");

    }

    if ($is_debug) {
        $modx->log(
            modX::LOG_LEVEL_INFO,
            'You in debug mode, so we process only 1 row. Time: ' . number_format(
                microtime(true) - $modx->startTime,
                7
            ) . " s"
        );
        exit;
    }
}

fclose($handle);

echo "Import complete in " . number_format(microtime(true) - $modx->startTime, 7) . " s
";
echo "Total rows: $rows
";
echo "Updated: $updated
";
if (!empty($not_updated)) {
    echo "Not updated (resources ids): " . implode(',', $not_updated);
}
Виталий
Вчера в 03:09
modx.pro
3
84
+3

Комментарии: 0

Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
0