Алексей Карташов

Алексей Карташов

Был в сети 23 ноября 2019, 13:47
Заказы не принимаю
Отлично, значит это не у меня проблема и всё сделал правильно. Спасибо!

И по мне так проблема надуманная.
Ок, дайте мне ссылку на какой-нибудь статичный html-сайт, который есть в топах по вкусным запросам — я его мигом оттуда выкину :-)

И да, такие сайты есть. И есть они потому, что делались давно и со временем начали занимать хорошие позиции в поиске.
Не обновляют их по простой причине — чтобы позиции не попортить, «а то мало ли...» :-)
Такой вариант (сперва распишу по пунктам, потом объясню логику):
1. Создать настройку, назвать её, к примеру, «mycomponent.frontend_page» (где «mycomponent» — это название вашего компонента).
2. Создать один ресурс, в котором планируется вывод данных из вашей таблицы или взять уже существующий.
К примеру, возьмём главную страницу сайта (id главной = 1).
3. Запишем в вышесозданную настройку цифру «1».

И вот теперь надо написать плагин на событие «OnPageNotFound». Логика его такова:
1. Разбираем урл. Примерно так:
// получаем массив с частями урла
$arr = parse_url($_SERVER['REQUEST_URI']);

// Регулярка, которая выберет все названия "папкок" из урла.
// К примеру урл имел вид http://www.site.ru/first1/second2/?sfgdg=tyu5466t35&qer=456#thisIsHash
// В $arr['path'] лежит строка вида "/first1/second2/"
// С помощью данной регулярки и функции preg_match_all мы получим массив, содержащий элементы:
// "first1", "second2", "third3" (в том порядке, в котором они были в урле).
//
$mask = "/([^\/]+)/";
preg_match_all($$mask, $arr['path'], $matches);

$pathes = $matches[0];

// Проверяем количество, чтобы отсечь заведомо другие урлы, в которых папок больше, чем нам нужно
// (а нужно нам "АлиасВида/АлиасКарточки")
// Не ноль и меньше 2х
if (count($pathes) && count($pathes) <= 2) {
	$i = 0;
	$good = false;
	foreach ($pathes as $path) {
		/**
		 * и вот здесь логика такая:
		 * на нулевом шаге ищем нужным нам "алиас вида" в собственной таблице (не забываем свой пакет через $modx->addPackage()).
		 * 
		 */
		switch ($i) {
			case 0:
				// здесь пишем название своего класса
				$vid = $modx->getObject('Vid', array(
					'alias' => $path
				));
				if ($vid instanceof 'Vid') {
					$good = true;
					$aliasVid = $path;
					// устанавливаем глобальный плейсхолдер, который будет доступен в шаблоне как [[+aliasVid]],
					// который можно будет использовать как угодно (например, подставить в условие сниппета pdoTools)
					$modx->setPlaceholder('aliasVid', $aliasVid);
				} else {
					break 2; // выходим из switch И ИЗ ЦИКЛА foreach (http://www.php.net/break)
				}
				break 1; // выходим из switch
				
			case 1:
				// здесь всё по аналогии, за исключением $good
				$kart = $modx->getObject('Kart', array(
					'alias' => $path
				));
				if ($kart instanceof 'Kart') {
					$aliasKart = $path;
					$modx->setPlaceholder('aliasKart', $aliasKart);
				}
				break;
		}
		
		$i++;
	}
	if ($good) {
		// если есть совпадения алиасов, то грузим документ, который записан в настройке
		$docId = $modx->getOption('mycomponent.frontend_page');
		if (!$docId) return;
		$modx->resource = $modx->getObject('modResource', $docId);
		$modx->request->prepareResponse();
		exit;
	}
}
Код не проверялся вообще!
Используйте его как пример логики (которая, кстати, тоже может быть не верной :-)).

Удачи!
А с точки зрения организации кода — можно ли запускать процессор из процессора?
Такого в родных процессорах я вроде не встречал и этого могут не принять.
Да и, скорей всего, это будет не правильно — ведь в процессорах на (un)publish/delete в конце чистится кеш, ставятся/снимаются блокировки — всё это и так делается в процессоре на update. Такого точно не примут.
Значит надо будет методы переносить и компоновать.