Миграция с 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. Поправил.            
                    
                            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.