Миграция с TV[type=image] в ms2Gallery
На днях стояла задача мигрировать все картинки из TV поля с типом «image» в ms2Gallery. Да при этом в контентах всех ресурсов заменить ссылку старого изображения из TV на новую ссылку из ms2Gallery. К тому-же в конце работы, чтоб удалял старые изображения с сервера, и данные в ТВшках о старых картинках.
Результат работы под катом.
Скрипт положить в корень или можно куда-нибудь глубже в папку и запустить из браузера (надёжнее из консоли).
Чтобы удалялись данные о старых изображениях надо выставить "$remove_old = 1".
Результат работы под катом.
Скрипт положить в корень или можно куда-нибудь глубже в папку и запустить из браузера (надёжнее из консоли).
Чтобы удалялись данные о старых изображениях надо выставить "$remove_old = 1".
<?php
// >> Подключаем
define('MODX_API_MODE', true);
$current_dir = dirname(__FILE__) .'/';
$index_php = $current_dir .'index.php';
$i=0;
while( !file_exists( $index_php ) && $i < 9 )
{
$current_dir = dirname(dirname($index_php)) .'/';
$index_php = $current_dir .'index.php';
$i++;
}
if( file_exists($index_php) )
{
require_once $index_php;
}
else {
print "Не удалось подгрузить MODX";
die;
}
// << Подключаем
// >> Включаем обработку ошибок
$modx->getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_ERROR);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
// << Включаем обработку ошибок
$modx->addPackage('ms2gallery', MODX_CORE_PATH . 'components/ms2gallery/model/'); // подключаем модель компонента "ms2Gallery"
$tv_id = '6'; // TV с типом Image
$remove_old = 0; // после заливки удалять данные из базы о ТВшке и старый файл с сервера?
// >> Выборка
$q = $modx->newQuery( 'modTemplateVarResource' );
$q->innerJoin(
'modTemplateVar',
'modTemplateVar',
'modTemplateVar.id = modTemplateVarResource.tmplvarid'
);
$q->select(
array(
'modTemplateVarResource.contentid as id',
'modTemplateVarResource.value as filepath',
'modTemplateVar.source as source',
)
);
$q->where( array(
'modTemplateVarResource.tmplvarid = "'. $tv_id .'"'.
' AND '.
'modTemplateVar.type = "image"'.
''));
$s = $q->prepare(); //print_r( $q->toSQL() ); die;
$s->execute();
$rows = $s->fetchAll(PDO::FETCH_ASSOC);
unset($q); unset($s);
//print_r( $rows ); die;
if( !is_array($rows) OR !count($rows) ) { print 'Ничего не найдено.'; die; }
// << Выборка
$modx->loadClass('sources.modMediaSource'); // подключаем класс modMediaSource
$slashes = array('////','///','//');
$_rows = $rows;
foreach( $rows as $k => $row )
{
// >> Получаем данные Источника Медиа
if( !is_object($mediaSource) )
{
$mediaSource = modMediaSource::getDefaultSource( $modx, $row['source'] );
//$mediaSource->set('ctx', $ctx);
$mediaSource->initialize();
}
$source_base_url = $mediaSource->getBaseUrl();
//print $source_base_url; die;
unset($mediaSource);
// << Получаем данные Источника Медиа
$filepath = substr( str_replace( $slashes, '/', '/'. $source_base_url .'/'. $row['filepath'] ), 1);
$filepath_full = $current_dir . substr( str_replace( $slashes, '/', '/'. $source_base_url .'/'. $row['filepath'] ), 1);
if( file_exists($filepath_full) )
{
//print $row['id'] . $filepath_full; die;
$response_upload = $modx->runProcessor('gallery/upload', array(
'file' => $filepath,
'id' => $row['id'],
),
array('processors_path' => MODX_CORE_PATH.'components/ms2gallery/processors/mgr/')
);
if( isset( $response_upload->response['object']['url'] ) )
{
$new_filepath = substr( str_replace( $slashes, '/', '/'. $response_upload->response['object']['url'] ), 1);
$new_filepath_full = $current_dir . substr( str_replace( $slashes, '/', '/'. $response_upload->response['object']['url'] ), 1);
if( file_exists($new_filepath_full) )
{
// >> Выборка и замена в ресурсах в поле "content" старого изображения на новое
$sql = "UPDATE {$modx->getTableName('modResource')} SET content = REPLACE(content, '". $filepath ."', '". $new_filepath ."') WHERE content LIKE '%". $filepath ."%'";
$q = $modx->prepare($sql);
$q->execute();
unset($q);
// << Выборка и замена в ресурсах в поле "content" старого изображения на новое
}
}
unset( $_rows[ array_search( $row, $_rows ) ] );
// >> Удаляем старые файл и данные TV, если перезалили в ms2Gallery
if( $remove_old )
{
if( isset( $response_upload->response['object']['url'] ) || ( isset( $response_upload->response['message'] ) && strstr( $response_upload->response['message'], 'уже есть' ) ) )
{
if( !search_in_array( $row['filepath'], $_rows ) )
{
unlink( $filepath_full );
}
$q = $modx->newQuery('modTemplateVarResource');
$q->command('delete');
$q->where(array(
'tmplvarid' => $tv_id,
'contentid' => $row['id'],
'value' => $row['filepath'],
));
$q->prepare();
//print $q->toSQL(); die;
$q->stmt->execute();
unset($q);
}
}
// << Удаляем старые файл и данные TV, если перезалили в ms2Gallery
unset($response_upload);
}
}
// >> Функция поиска в многомерном массиве
function search_in_array( $value, $array )
{
foreach( $array as $k => $v )
{
if( array_search( $value, $v ) )
{
return true;
}
}
return false;
}
// << Функция поиска в многомерном массиве
Поблагодарить автора
Отправить деньги
Комментарии: 8
Какое то страшное подключение modx api. Это все делается в 5 строчек:
require_once 'config.core.php';
require_once MODX_CORE_PATH.'model/modx/modx.class.php';
$modx = new modX();
$modx->initialize('web');
$modx->getService('error','error.modError', '', '');
Перепишите для себя. Я для себя писал и мне удобно, чтобы скрипт можно было сунуть куда-нибудь.
Ваше дело как поступить. Я лишь поправил скрипт подключения для тех, кто будет использовать его в дальнейшем.
А в чём отличие Вашего метода подключения и того, что у меня, если не считать множества проверок на существование файла index.php в моём скрипте?
Мне действительно интересно, может я что-то делаю не так…
Мне действительно интересно, может я что-то делаю не так…
В моем случае корректно подключается modx и создается обьект, у вас я не вижу этого, вполне вероятно что способ работоспособный, но на сколько правильный — я тут сказать не могу.
Разве в index.php не происходит тоже самое?)
К слову:
К слову:
Это все делается в 5 строчекТем способом, которым воспользовался я это можно сделать в 3 строчки:
define('MODX_API_MODE', true);
require_once dirname(__FILE__) . '/index.php';
$modx->getService('error','error.modError');
Это если Вам нравится делать всё компактно.
Да, я тоже так делаю.
Но и в готовом скрипте такую портянку с нахождением index.php оставлять не стоит. Или убрать совсем, или переписать поиск в цикле на n директорий вверх.
Но и в готовом скрипте такую портянку с нахождением index.php оставлять не стоит. Или убрать совсем, или переписать поиск в цикле на n директорий вверх.
Вот за это спасибо, Василий. Долго думал, как лучше сделать проверку и цикл while почему-то не рассматривал, как вариант. После твоих слов сразу в голову пришёл while. Поправил.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.