Igor Ivanov

Igor Ivanov

С нами с 19 марта 2013; Место в рейтинге пользователей: #349
Юрий Фомин
27 января 2017, 18:56
3
+2
Таки дописал велосипед про автоматизацию создания/удаления и редактирования ресурсов в контекстах-дублях.

<?php
if ($modx->event->name == 'OnDocFormSave') {
    // собираем дублированные контексты (web - оригинальный контекст)
	$contexts = $modx->getCollection('modContext', array('key:NOT IN' => ['mgr','web']));
	
	// получаем родителя создаваемого ресурса
	$parent = $resource->get('parent');
	if ($parent != '0') {
        $parentId = $modx->getObject('modResource', $parent);
        $parentAlias = $parentId->get('alias');
	}
    $alias = $resource->get('alias');
    $id = $resource->get('id');
    // проходимся по контекстам
	foreach ($contexts as $context) {
	    
	    $response = $modx->getObject('modResource', array('context_key'=>$context->key, 'alias' => $alias));
	    // если ресурс уже существует то тогда просто обновляем поля (кроме контента)
	    if ($response) {
    	    $response->set('pagetitle', $resource->get('pagetitle'));
    	    $response->set('longtitle', $resource->get('longtitle'));
    	    $response->set('description', $resource->get('description'));
    	    $response->set('content', '[[!OriginalFields?&id=`'.$id.'`&field=`content`]]');
            // ... много остальных полей
    	    $response->set('deleted', $resource->get('deleted'));
    	    $response->save();
	    } else {
	        // создание нового ресурса
    	    $newResource = $modx->newObject('modDocument');
    	    // заполняем поля ресурса
    	    $newResource->set('context_key', $context->key);
    	    $newResource->set('pagetitle', $resource->get('pagetitle'));
    	    $newResource->set('longtitle', $resource->get('longtitle'));
    	    $newResource->set('description', $resource->get('description'));
    	    $newResource->set('content', '[[!OriginalFields?&id=`'.$id.'`&field=`content`]]');
            // ... много остальных полей
    	    $newResource->set('deleted', $resource->get('deleted'));
    	    
    	    // поле родителя для создания дубля в нем а не в корне
    	    if ($parent != '0') {
    	        $res = $modx->getObject('modResource', array('context_key'=>$context->key, 'alias'=>$parentAlias));
    	        $parntId = $res->get('id');
    	    } else {
    	        $parntId = $parent;
    	    }
    	    $newResource->set('parent', $parntId);
            // сохраняем свежеиспеченый ресурс
    		$newResource->save();
	    }
	}
	// очищаем кеш
	$modx->cacheManager->clearCache();
}

// удаление ресурсов в дублирующих контекстах
if ($modx->event->name == 'OnDocFormDelete') {
    // собираем дублированные контексты (web - оригинальный контекст)
    $contexts = $modx->getCollection('modContext', array('key:NOT IN' => ['mgr','web']));
    
    // проходимся по контекстам
    foreach ($contexts as $context) {
        
        // получаем нужные (верней не нужные поэтому и удаляемые) нам ресурсы
        $response = $modx->getObject('modResource', array('context_key'=>$context->key, 'alias' => $resource->get('alias')));
        
        // помечаем как удаленные
        $response->set('deleted', $resource->get('deleted'));
        $response->save();
        
        // удаляет полностью
        // $response->get('id');
        // $response->remove();
    }
	$modx->cacheManager->clearCache();
}
Fi1osof
14 января 2017, 04:04
5
+4
Здесь важно учесть следующий момент: проиндексирован http-сайт уже или нет. Если нет, то можно смело сразу зарубать на https с настройкой редиректа. А если да, то такая процедура запросто может выбить сайт из индекса на месяц-два, а то и больше (что вряд ли кому-то понравится). Дело в том, что http — Это 80-ый порт, а https — 443. Для поисковиков это разные сайты (технически ведь на разных портах могут быть разные сайты и может быть разный контент). И получается, что новый сайт еще не проиндексирован, а новый (https) еще не индексированный. По этой причине надо делать сайт доступным и по http и по https. Но тут возникает еще один момент: Страницы в MODX кешируются и могут возникать случаи, когда на http-страницах все ссылки на https и наоборот. Если с https-ссылками http- страницах еще не особо страшно, то на https-страницах это может приводить к тому, что часть контента просто не будет подгружаться (браузер заблокирует соединения на http с https-страниц). Я в таких случаях на сайте прописываю такой плагин:
if($modx->context->key == 'mgr'){
    return;
}
 
switch($modx->event->name){
    
    case 'OnMODXInit':
    // case 'OnHandleRequest':
        
        if(!empty($_SERVER['SERVER_PORT']) AND $_SERVER['SERVER_PORT'] == '443'){
            
            $modx->setOption('server_protocol', 'https');
            
            $modx->setOption('site_url', 'https://' . $modx->getOption('http_host', null) . $modx->getOption('base_url', null));
            
            $cache_prefix = $modx->getOption('cache_prefix', null, '/') . '443/';
            $modx->setOption('cache_prefix', $cache_prefix);
        }
        
        break;
}
Суть его в том, чтобы кеш-префикс поменять для https-запросов.
Важно: на разных хостингах вместо $_SERVER['SERVER_PORT'] может быть другой параметр, надо смотреть индивидуально

Тогда сайт не будет потерян поисковиком и не вызовет выпода из индекса.
В robots.txt еще надо прописать жестко Host: site_domain.
После этого месяца через три (когда поисковики полностью перестроят индексы), можно уже будет настроить и редирект.
Дмитрий Суворов
24 декабря 2016, 16:49
1
0
как вариант (ибо другого пути у вас нет) необходимо все же перейти на опции, так как они не затираются. А чтобы перенести данные из TV в опции — можно использовать плагин. Если мне не изменяет память, если его повесить на событие OnDocFormSave, то при прогоне импорта он сработает до того, как очистятся TV, и данные перенесутся — но я не уверен. Вот сам плагин:

<?php
if($resource->class_key == 'msProduct' && $modx->event->name == 'OnDocFormSave'){
	$soputId = $resource->getTVValue('soput-product');
	
	if ($soputId == '') {
	    $soputId2 = $resource->get('dop-products');
	    $resource->setTVValue('soput-product', $soputId2);
	    $resource->save();
	} else {
        $resource->set('dop-products', $soputId);
	    $resource->save();
	}
}

Как-то было дело я с этим тоже сталкивался, правда там было 2 TV)
TiEdamn
15 ноября 2016, 16:07
2
+1
Проблема решилась, в случае моего хостинга в файле htaccess требовалось указать следующие строки:

RewriteEngine On
RewriteBase /
RewriteCond %{ENV:REDIRECT_STATUS} !^$
RewriteRule .* - [L]

А именно без 3 и 4 строки ломались ЧПУ. Надеюсь кому-нибудь поможет, кто испытывает подобные проблемы.
Александр
20 октября 2016, 19:26
3
0
Где-то использовал вот такой код чтобы не переделывать back-end:

$('.comparison-row .comparison-head').each(function () {
         $.ajaxSetup({async: false});
         $.post(document.location.href, {cmp_action: 'remove', list: $(this).data('list'), resource: $(this).find("input[name='id']").val()}, function(response) {}, 'json');
         $.ajaxSetup({async: true});
         document.location.reload();
});

Это подходит для версии пакета Comparison 1.0.0

Повесить можно на любое событие
Сергей
04 октября 2016, 12:40
1
+2
Попробуйте в группу пользователей добавить добавить политику доступа для minishop. prntscr.com/cpmu9d
Дима Сайт old см. профиль
03 октября 2016, 00:57
1
0
не пойму какие чанки
tpl – чанк для оформления ресурса, то есть каждого элемента li внутри ul. По умолчанию
tplInner – чанк для обёртки внутренних пунктов меню, то есть оформляет меню 2-го уровня
tplInnerRow – чанк обёртка внутреннего пункта меню. Оформляет li вложенные в ul в меню 2-го уровня, заменяет собой tpl
Вам по идее вот эти нужны. Внутри tpl и/или tplInnerRow вызывайте pdoResources со своим каталогом.

как правильно обернуть в таком случае конечный ресурс?
Тут зависит все от того, что вы хотите от этого ресурса вывести. Если только название, то можно вообще обойтись одним pdoMenu, он и так построит дерево с названиями всех разделов и конечных пунктов.

P.S. Советую больше экспериментировать, вы не сломаете тестовый сайт если пару раз не правильно укажете параметры, зато быстро разберетесь!
Антон
02 октября 2016, 03:02
2
+2
Пересборка тумбов.
Просто создать любой qwerty.php файл в корне сайта и запустить из браузера.
<?php
define('MODX_API_MODE', true);
require 'index.php';		// Если файл лежит не в корне - здесь нужно указать верный путь
$modx->getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_INFO);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');

if (!isset($parents)) {$parents = 0;}		// Можно указать список категорий для поиска товаров
if (!isset($resources)) {$resources = '';}	// Можно указать конкретный список товаров

$pdo = $modx->getService('pdoFetch');
$condition = array('parents' => $parents);
$files = $pdo->getCollection('msProduct',
	array(
		'msProduct.class_key' => 'msProduct',
	),
	array(
		'class' => 'msProduct',
		'parents' => $parents,
		'resources' => $resources,
		'innerJoin' => array(
			'msProductFile' => array(
				'alias' => 'msProductFile',
				'on' => array(
					'msProduct.id = msProductFile.product_id',
					'msProductFile.parent' => 0,
					'msProductFile.type' => 'image',
				)
			)
		),
		'select' => array(
			'msProductFile' => 'all'
		),
		'sortby' => 'msProduct.id'
	)
);

echo '<pre>';
echo $pdo->getTime();
foreach ($files as $row) {
	$file = $modx->newObject('msProductFile');	
	$file->fromArray($row, '', true, true);
	
	$children = $file->getMany('Children');
	foreach ($children as $child) {
		$child->remove();
	}
	$file->generateThumbnails();
	
	// Обновляем thumb и image товара
	if ($product = $file->getOne('Product')) {
		$product->updateProductImage();
	}
}

echo microtime(true) - $modx->startTime;
but1head
29 сентября 2016, 23:09
1
-1
Если нужно что бы tv в админке показывал pagetitle, а выбирал id
@SELECT pagetitle, id FROM modx_site_content WHERE parent=35
внутри tv в «возможные значения».

Если вопрос про фронтэнду — Илья выше привел пример.