[miniShop2] - Перенос изображений в Selectel
В данном топике решается проблема переноса изображений с сайта на Selectel Cloud Storage.
Ситуация с которой пришлось столкнуться — магазин наполнялся и все было хорошо, в какой то момент решили перейти на облачное хранилище. По хорошему нужно было создать новый медиасорс и его привязаться к Selectel, а затем задать его по дефолту, но было сделано иначе. Просто MS2 Images настроили на Selectel и дальше приняли спокойно наполнять.
И вроде бы все нормально, но… что же со старыми файлами что лежат на хостинге? А да, с ними проблемка…
Под катом скрипт для переноса вот таких изображений в облако.
— Первое, наперво сделать бэкап.
— Второе
Создать медиасорс TMP и задать в нем несуществующий путь, например
Чтобы физически они не удалялись нужен данный фокус.
— Третье
Создать файлик, где вам удобно и поместить в него следующий код
gist.github.com/vgrish/f6cf18f77f52058b4db2289c7795b78b
в данном случае
В данном случае еще какой то проблемный хостинг и там напряженка с фпт, консолью и тд. потому скрипт запускается в браузере.
Написан на скорую руку и прошу строго не судить. Возможно кому то поможет выйти из сложившейся ситуации.
PS. Все спасибо за внимание. НЕ ЗАБЫВАЕМ ПРО БЭКАП!!!
Ситуация с которой пришлось столкнуться — магазин наполнялся и все было хорошо, в какой то момент решили перейти на облачное хранилище. По хорошему нужно было создать новый медиасорс и его привязаться к Selectel, а затем задать его по дефолту, но было сделано иначе. Просто MS2 Images настроили на Selectel и дальше приняли спокойно наполнять.
И вроде бы все нормально, но… что же со старыми файлами что лежат на хостинге? А да, с ними проблемка…
Под катом скрипт для переноса вот таких изображений в облако.
— Первое, наперво сделать бэкап.
— Второе
Создать медиасорс TMP и задать в нем несуществующий путь, например
basePath - assets/images/products/tmp/
В процессе обработки будет задавать продукту source TMP и удалять старые изображения из БД.Чтобы физически они не удалялись нужен данный фокус.
— Третье
Создать файлик, где вам удобно и поместить в него следующий код
gist.github.com/vgrish/f6cf18f77f52058b4db2289c7795b78b
<?php
ini_set('display_errors', 1);
ini_set('error_reporting', -1);
define('MODX_API_MODE', true);
$productionConfig = (dirname(dirname(__FILE__))) . '/index.php';
if (file_exists($productionConfig)) {
/** @noinspection PhpIncludeInspection */
require_once $productionConfig;
} else {
die;
}
// load services
$modx->setLogTarget('FILE');
$modx->setLogLevel(modX::LOG_LEVEL_ERROR);
$modx->getService('error', 'error.modError');
$modx->error->message = null;
// 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);
$path = MODX_BASE_PATH . 'assets/images/products/';
$q = $modx->newQuery('msProduct');
$q->innerJoin('msProductFile', 'msProductFile', 'msProduct.id = msProductFile.product_id');
$q->where(array(
'msProductFile.parent' => 0,
'msProductFile.url:LIKE' => '%/assets/images/products/%',
));
$q->sortby('msProduct.id', 'ASC');
$q->limit(1);
/** @var msProduct $product */
$product = $modx->getObject('msProduct', $q);
if ($product) {
$modx->log(modX::LOG_LEVEL_ERROR, "Process product " . $product->get('id'));
$files = scandir($path . $product->get('id'));
foreach ($files as $idx => $file) {
if ($file == '.' || $file == '..') {
unset($files[$idx]);
continue;
};
if (is_dir($path . $product->get('id') . '/' . $file)) {
unset($files[$idx]);
continue;
}
$files[$idx] = $path . $product->get('id') . '/' . $file;
}
$modx->log(modX::LOG_LEVEL_ERROR, print_r($files, 1));
// set TMP source
$product->set('source', 3);
$product->save();
/** @var msProductFile[] $images */
$images = $product->getMany('Files', array('parent' => 0, 'url:LIKE' => '%/assets/images/products/%',));
foreach ($images as $image) {
$image->remove();
}
// set MS2 Images source
$product->set('source', 2);
$product->save();
if (!empty($files)) {
foreach ($files as $image) {
$name = explode('/', $image);
$name = end($name);
if (!file_exists($image)) {
$modx->log(modX::LOG_LEVEL_ERROR, "Could not import image \"$v\" to gallery. File \"$image\" not found on server.");
} else {
$response = $modx->runProcessor('gallery/upload',
array('id' => $product->get('id'), 'name' => $name, 'file' => $image),
array('processors_path' => MODX_CORE_PATH . 'components/minishop2/processors/mgr/')
);
if ($response->isError()) {
$modx->log(modX::LOG_LEVEL_ERROR, "Error on upload \"$v\": \n" . print_r($response->getAllErrors(), 1));
} else {
$modx->log(modX::LOG_LEVEL_INFO, "Successful upload \"$v\": \n" . print_r($response->getObject(), 1));
}
}
}
}
}
$count = $modx->getCount('msProductFile', array(
'parent' => 0,
'url:LIKE' => '%/assets/images/products/%',
));
$modx->log(modX::LOG_LEVEL_ERROR, "Total " . $count);
if ($count AND $product) {
$uri = parse_url($_SERVER['REQUEST_URI']);
$siteUrl = $modx->getOption('site_url', null, MODX_SITE_URL);
$stepRedirect = trim($siteUrl, '/') . $uri['path'];
$refreshDelay = 2;
header("Refresh: {$refreshDelay}; url={$stepRedirect}");
} else {
$modx->log(modX::LOG_LEVEL_ERROR, "Process product END");
}
в данном случае
TMP source - идентификатор 3
MS2 Images source - идентификатор 2
Если у вас другие идентификаторы, то сделайте замену по коду.В данном случае еще какой то проблемный хостинг и там напряженка с фпт, консолью и тд. потому скрипт запускается в браузере.
Написан на скорую руку и прошу строго не судить. Возможно кому то поможет выйти из сложившейся ситуации.
PS. Все спасибо за внимание. НЕ ЗАБЫВАЕМ ПРО БЭКАП!!!
Поблагодарить автора
Отправить деньги
Комментарии: 2
Спасибо! Очень кстати пришлось.
А простое обновление превью через процессор «mgr/gallery/generate»
Старые изображения из бд удалятся? Если нет, то как тогда можно почистить от мусора таблицу? А то такое чувство что в ней записей раза в 2 больше чем нужно.
$resources = $modx->getCollection('msProductFile', $q);
foreach ($resources as $resource) {
$modx->runProcessor('mgr/gallery/generate', array('id' => $resource->id),
array('processors_path' => $modx->getOption('core_path').'components/minishop2/processors/'));
}
не подойдет, если файлы заранее перенес в Selectel?Старые изображения из бд удалятся? Если нет, то как тогда можно почистить от мусора таблицу? А то такое чувство что в ней записей раза в 2 больше чем нужно.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.