UMIhelp

Разработка сайта на UMI.CMS => Настройка системы и модулей => Тема начата: 0xDEFACE от 25 Апреля 2016, 12:55:46

Название: getIdByPath по части пути
Отправлено: 0xDEFACE от 25 Апреля 2016, 12:55:46
Коллеги!

Есть страница site.ru/katalog/razdel/subrazdel/super-item/

Задача:
При обращении к site.ru/super-item/ получить id страницы "/katalog/razdel/subrazdel/super-item/".

Эксперименты с getIdByPath - показали, что она умеет возвращать id только по полному пути, но не по последней части.

$hierarchy = umiHierarchy::getInstance();
$original_id = $hierarchy->getIdByPath('/super-item/', true, $errors_count);
- возвращает false.

Да, можно подключиться напрямую к БД и сделать необходимую выборку, но может есть решение средствами UMI? Не могу найти исходник getIdByPath, его бы чуть-чуть модифицировать или лучше сделать кастомный вариант на основе оригинала.
Название: Re: getIdByPath по части пути
Отправлено: aghigay от 25 Апреля 2016, 13:00:49
super-item - может быть не уникальным в рамках сайта. Может быть 10-20-30-100 таких страниц на разных уровнях вложенности. Так что, как минимум, даже если вы напишите такую функцию - можно будет получить случайно несколько id вместо одного.

А вообще, можно взять Selector и проверять по http://api.docs.umi-cms.ru/razrabotka_nestandartnogo_funkcionala/proizvolnye_vyborki/selector/#sel=53:1,53:9
Название: Re: getIdByPath по части пути
Отправлено: 0xDEFACE от 25 Апреля 2016, 14:24:20
Получилось, спасибо!

$pages = new selector('pages');
$pages->types('hierarchy-type')->name('catalog', 'object');

$new_id = "";

foreach($pages as $page)
{
if ($page->getAltName() == $parsed_uri[1])
{
$new_id = $page->getId();
break;
}
}
Подскажите ещё, пож-та, как указать найденный $new_id, чтобы вместо 404 "бралась" и выводилась нужная страница? Контент страницы генерируется этим:

$globalVars = $cmsController->getGlobalVariables();
Если обращаться к site.ru/super-item/, то по понятным причинам генерируется notfound. Как сообщить $cmsController, чтобы он работал с найденным $new_id?

P.S. Работаю с файликом libs/root-src/index.php
Название: Re: getIdByPath по части пути
Отправлено: aghigay от 25 Апреля 2016, 14:58:55
А может не стоит этого делать? Если есть желание сделать чтобы по пути товара открывался товар - может проще сделать виртуальную копию всех товаров?
Название: Re: getIdByPath по части пути
Отправлено: 0xDEFACE от 25 Апреля 2016, 15:02:54
А может не стоит этого делать? Если есть желание сделать чтобы по пути товара открывался товар - может проще сделать виртуальную копию всех товаров?
Изначально был такой план. Но нужно что бы при обращении к site.ru/super-item/ хлебные крошки были как у "/katalog/razdel/subrazdel/super-item/":
Ktalog -> Razdel -> Subrazdel
Название: Re: getIdByPath по части пути
Отправлено: aghigay от 25 Апреля 2016, 15:08:41
Если проблема только в хлебных крошках и если не обязательно чтобы URL оставался прежним, то берете http://wiki.umisoft.ru/%D0%9E%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D1%8B_%D1%81_%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D0%BE%D0%B9_%D0%B1%D1%8B%D0%BB%D0%B0_%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D0%BD%D0%B0_%D0%B2%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BF%D0%B8%D1%8F определяете основную страницу и редиректите на неё.

Можно конечно попытаться завязаться на htaccess и с ним побаловаться, но, как мне кажется, это будет просто лишней тратой времени и сил.
Название: Re: getIdByPath по части пути
Отправлено: 0xDEFACE от 25 Апреля 2016, 15:36:29
Адреса важно сохранить: /katalog/razdel/subrazdel/super-item/ должен равняться "/super-item/", а вирт копии создаются с другим alt-name...
Название: Re: getIdByPath по части пути
Отправлено: aghigay от 26 Апреля 2016, 00:12:38
Тогда, вероятнее всего, вам потребуется разбираться с http://www.htaccess.net.ru/doc/mod_rewrite/RewriteCond.php Но это уже не вопрос ЮМИ

Но вы должны понимать, что с точки зрения поисковой системы страницы /katalog/razdel/subrazdel/super-item/ и /super-item/ будут неразличимы. Следовательно, стоит позаботиться о правильной склейке этих страниц, canonical и прочее.
Название: Re: getIdByPath по части пути
Отправлено: 0xDEFACE от 26 Апреля 2016, 12:37:02
Я уже вчера осилил эту таску. Увы, без жертв среди системных файлов движка не обошлось. Добавил что-то вроде этого в /classes/system/subsystems/cmsController/cmsController.php

public function setDirectElementId()
{
$parsed_uri = explode('/', trim($_SERVER["REQUEST_URI"]));
if (count($parsed_uri) == 3)
{
$pages = new selector('pages');
$pages->types('hierarchy-type')->name('catalog', 'object');
foreach($pages as $page)
{
if ($page->getAltName() == $parsed_uri[1])
{
$this->current_element_id = $page->getId();
$this->setCurrentMethod("object");
$this->setCurrentModule("catalog");
break;
}
}
}
}
и вызвал из analyzePath()

Редирект с /katalog/razdel/subrazdel/super-item/ и /super-item/ оказалось самой простой задачей ( /libs/root-src/index.php )

if ( ($currentMethod == "object") && ($currentModule == "catalog") )
{
if ( strpos($this_uri, '/katalog/') !== false )
{
$original_uri = $parsed_uri[count($parsed_uri) - 2]."/";
$buffer->redirect('http://'.$host."/".$original_uri, '301 Moved Permanently', 301);
}
}
Единственное, что меня смущает, так это реализация поиска id элемента по alt_name (через selector). Я перебираю все выбранные варианты в foreach, но может это как-то сделать с использованием where(), быстрее было бы?
Название: Re: getIdByPath по части пути
Отправлено: aghigay от 26 Апреля 2016, 17:14:02
Грусть.... Модификация системных файлов аукнется вам при следующем обновлении. Так что не забудьте задокументировать изменения и сделать копию, чтобы иметь возможность восстановить указанный функционал после обновления.
Название: Re: getIdByPath по части пути
Отправлено: 0xDEFACE от 26 Апреля 2016, 17:49:47
Цитировать
Так что не забудьте задокументировать изменения и сделать копию, чтобы иметь возможность восстановить указанный функционал после обновления.
Я в курсе, спасибо. Не впервой :)