Как сгенерировать алиас с помощью Translit?
Как использовать возможности пакета translit для генерации транслитерированных алиасов?
Дело в том, что мне пришлось перегенерировать все uri ресуросв (с разным class_key). Использовал советы отсюда и отсюда.
В итоге у меня получился такой скомбинированный вариант, который я запускаю в консоли:
Задача: хочу сам, ручками, используя возможности translit сгенерировать alias и записать ресурсам с пустыми алиасами. А после этого уже разбираться с uri.
Дело в том, что мне пришлось перегенерировать все uri ресуросв (с разным class_key). Использовал советы отсюда и отсюда.
В итоге у меня получился такой скомбинированный вариант, который я запускаю в консоли:
<?php
ini_set("display_errors",1);
error_reporting(E_ALL);
header("Content-Type: text/html; charset=utf-8");
// Подключаем
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');
$modx->exec("UPDATE modx_site_content SET uri='' WHERE alias=''");
$modx->exec("UPDATE modx_site_content SET uri = '' WHERE uri=alias");//удаляет uri равное alias
$modx->exec("UPDATE modx_site_content SET uri = '' WHERE alias = CONCAT(uri, '/')");//удаляет uri со слешем на конце равное alias
$modx->exec("UPDATE modx_site_content t1, (SELECT uri FROM modx_site_content GROUP BY uri HAVING COUNT(*) > 1)
t2 SET t1.uri = '' WHERE t2.uri = t1.uri AND uri_override = 0");//удаляет дубликаты uri на всякий пожарный
$modx->setLogLevel(1);
ini_set('max_execution_time', 7200);
ignore_user_abort(true);
$q = $modx->newQuery('modResource');
$q->andCondition(array(
'uri' => null,
'OR:uri:=' => '',
'OR:alias:=' => ''
));
$q->sortby('id');
$q->limit(3000);
$rows = $updated = 0;
$s = $q->prepare();
$s->execute();
foreach($modx->getCollection('modResource', $q) as $data){
$rows++;
$modx->error->reset();
$modx->runProcessor('resource/update', $data->toArray());
if($modx->error->hasError()){
print_r($modx->error->getErrors());
echo "\nНе обработана строка\n";
}
else {
$updated++;
echo "\nОБРАБОТАНО\n";
}
}
echo "\n==========================================\n";
echo "Всего найдено документов по условию: ". $modx->getCount('modResource', $q)."\n";
echo "\nОбработано строк: $rows\n";
echo "\nОбновлено: $updated\n\n\n";
С помощью такого подхода получилось обновить у половины ресурсов, остальная половина упрямо даёт результат Обновлено: 0. Комбинировал результаты этого скрипта как только мог.Задача: хочу сам, ручками, используя возможности translit сгенерировать alias и записать ресурсам с пустыми алиасами. А после этого уже разбираться с uri.
Поблагодарить автора
Отправить деньги
Комментарии: 17
Уже 2 дня занимаюсь обновлением alias-ов и uri…
Ресурсов довольно много, около 10 тысяч.
Ресурсов довольно много, около 10 тысяч.
У ресурса есть метод cleanAlias, который генерирует псевдоним:
$title = $data->get('pagetitle') . '-' . $data->get('id');
$alias = $data->cleanAlias($title);
$data->set('alias', $alias);
$modx->runProcessor('resource/update', $resource->toArray());
Давно задавался вопросом — возможно ли вызвать метод
->cleanAlias($title);
не создавая ресурс? Недавно что-то читал по статическим методам в классах — это такой особый метод, который доступен без создания экземпляра объекта. Так вот, является ли метод ->cleanAlias(); статическием? и если да, как его вызвать не создавая объект resource?
Можно же создать экземпляр класса, использовать его методы, а в базу его не записывать (не вызывать ->save())
$generator = $modx->newObject('modResource');
foreach ($files as $file) {
$file['name'] = $generator->cleanAlias($file['name']);
}
это да. интересовало мнение специалиста ООП -) так собственно и делается, просто не вызывается метод
->save();
. Но тогда где прелести статических методов? ))
В реализации это не статический метод, на то есть причины. Достаточно посмотреть в исходники.
public function cleanAlias($alias, array $options = array()) {
return $this->xpdo->call($this->_class, 'filterPathSegment', array(&$this->xpdo, $alias, $options));
}
Как видно, вызывается функция filterPathSegment в то же классе, которая уже отвечает за обработку непосредственно. Вот она уже статическая и при желании ее можно использовать напрямую. modResource::filterPathSegment($modx, $alias);
да похоже что можно, только это приведет к «разрастанию» кода, что авторы модкс не допускают. Пару лет назад Марк сделал пулл-реквест, но он не прошел: github.com/modxcms/revolution/pull/620
Я выше написал как можно сделать, Джейсон другое решение предложил.
Классно, спасибо за этот метод! Но он почему-то не срабатывает.
Я выбрал только один ресурс по id чтобы понаблюдать как заполнится поле alias у него, наблюдаю в phpMyAdmin. Но после срабатывания кода и попытки запуска процессора обновления поле остаётся пустым, то есть обновление не произошло!
Вот изменённый код:
Я выбрал только один ресурс по id чтобы понаблюдать как заполнится поле alias у него, наблюдаю в phpMyAdmin. Но после срабатывания кода и попытки запуска процессора обновления поле остаётся пустым, то есть обновление не произошло!
Вот изменённый код:
<?php
ini_set("display_errors",1);
error_reporting(E_ALL);
header("Content-Type: text/html; charset=utf-8");
// Подключаем
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');
// $modx->exec("UPDATE modx_site_content WHERE uri='prezentaczii/' SET uri=''");
// $modx->exec("UPDATE modx_site_content WHERE uri='informacziya/' SET uri=''");
// // $modx->exec("UPDATE modx_site_content SET uri = '' WHERE uri=alias");//удаляет uri равное alias
$modx->exec("UPDATE modx_site_content SET uri='' WHERE alias=''");
$modx->exec("UPDATE modx_site_content SET uri = '' WHERE alias = CONCAT(uri, '/')");//удаляет uri со слешем на конце равное alias
$modx->exec("UPDATE modx_site_content t1, (SELECT uri FROM modx_site_content GROUP BY uri HAVING COUNT(*) > 1)
t2 SET t1.uri = '' WHERE t2.uri = t1.uri AND uri_override = 0");//удаляет дубликаты uri на всякий пожарный
$modx->setLogLevel(1);
ini_set('max_execution_time', 7200);
ignore_user_abort(true);
$q = $modx->newQuery('modResource', array('id'=>'85'));
$q->andCondition(array(
'uri' => null,
'OR:uri:=' => '',
'OR:alias:=' => ''
));
$q->sortby('id');
$q->limit(1);
$rows = $updated = 0;
$s = $q->prepare();
$s->execute();
foreach($modx->getCollection('modResource', $q) as $data){
$rows++;
$modx->error->reset();
$title = $data->get('pagetitle') . '-' . $data->get('id');
$alias = $data->cleanAlias($title);
$data->set('alias', $alias);
$modx->runProcessor('resource/update', $data->toArray());
if($modx->error->hasError()){
print_r($modx->error->getErrors());
echo "\nНе обработана строка\n".$data->get('pagetitle');
}
else {
$updated++;
echo "\nОБРАБОТАНО\n".$data->get('pagetitle');
}
}
print "\n==========================================\nВсего найдено документов по условию: ". $modx->getCount('modResource', $q)."\n";
echo "\nОбработано строк: $rows\n";
echo "\nОбновлено: $updated\n\n\n";
Результат выполнения кода:Не обработана строка Тут название ресурса с id = 85
==========================================
Всего найдено документов по условию: 1
Обработано строк: 1
Обновлено: 0
Или записать alias напрямую, без процессоров?
Можно и напрямую, тогда надо будет самостоятельно сгенерировать еще и поле URI
Спасибо тебе!
Этот кусок кода успешно записал мне alias-ы:
Этот кусок кода успешно записал мне alias-ы:
foreach($modx->getCollection('modResource', $q) as $data){
$title = $data->get('pagetitle');
$id = $data->get('id');
$alias = $data->cleanAlias($title);
$data->set('alias', $alias);
if($modx->exec("UPDATE modx_site_content SET alias='$alias' WHERE id ='$id'")) {
echo "\nНе обработана строка: ".$data->get('pagetitle')." == ".$alias;
}
else {
$updated++;
echo "\nОБРАБОТАНО: ".$data->get('pagetitle')." == ".$alias;
}
}
но с URI пока не могу разобраться, что именно из тех строк что ты мне показал использовать…
Если я не ошибаюсь, то вот этот метод формирует URI:
$aliasPath = $data->getAliasPath($alias);
Да, видимо, будет достаточно запустить так
$aliasPath = $data->getAliasPath();
github.com/modxcms/revolution/blob/0660b5955e1307dbaff8ab3c8750bad0b4d674ef/core/model/modx/modresource.class.php#L868-L923
Точно, супер, работает! Как всё просто! Спасибо!
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.